@djangocfg/ui-tools 2.1.134 → 2.1.135
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CronScheduler.client-X74RLZLW.cjs → CronScheduler.client-Q6HLKGLR.cjs} +11 -11
- package/dist/{CronScheduler.client-X74RLZLW.cjs.map → CronScheduler.client-Q6HLKGLR.cjs.map} +1 -1
- package/dist/{CronScheduler.client-BYKMIOZJ.mjs → CronScheduler.client-T42ZXXOG.mjs} +3 -3
- package/dist/{CronScheduler.client-BYKMIOZJ.mjs.map → CronScheduler.client-T42ZXXOG.mjs.map} +1 -1
- package/dist/{chunk-HVRP57NM.mjs → chunk-7H4LDBIH.mjs} +71 -45
- package/dist/chunk-7H4LDBIH.mjs.map +1 -0
- package/dist/{chunk-D3TZQSX6.cjs → chunk-WU6ZLOL4.cjs} +71 -45
- package/dist/chunk-WU6ZLOL4.cjs.map +1 -0
- package/dist/index.cjs +22 -22
- package/dist/index.mjs +3 -3
- package/package.json +6 -6
- package/src/tools/CronScheduler/components/DayChips.tsx +7 -4
- package/src/tools/CronScheduler/components/MonthDayGrid.tsx +8 -5
- package/src/tools/CronScheduler/context/CronSchedulerContext.tsx +17 -9
- package/src/tools/CronScheduler/utils/cron-builder.ts +15 -6
- package/src/tools/CronScheduler/utils/cron-parser.ts +54 -18
- package/dist/chunk-D3TZQSX6.cjs.map +0 -1
- package/dist/chunk-HVRP57NM.mjs.map +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var chunkWU6ZLOL4_cjs = require('./chunk-WU6ZLOL4.cjs');
|
|
6
6
|
var chunkWGEGR3DF_cjs = require('./chunk-WGEGR3DF.cjs');
|
|
7
7
|
var lib = require('@djangocfg/ui-core/lib');
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -15,15 +15,15 @@ function CronSchedulerInner({
|
|
|
15
15
|
disabled,
|
|
16
16
|
className
|
|
17
17
|
}) {
|
|
18
|
-
const { type } =
|
|
18
|
+
const { type } = chunkWU6ZLOL4_cjs.useCronType();
|
|
19
19
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: lib.cn("space-y-3", className), children: [
|
|
20
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21
|
-
type !== "custom" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22
|
-
type === "weekly" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
23
|
-
type === "monthly" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
24
|
-
type === "custom" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
20
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkWU6ZLOL4_cjs.ScheduleTypeSelector, { disabled }),
|
|
21
|
+
type !== "custom" && /* @__PURE__ */ jsxRuntime.jsx(chunkWU6ZLOL4_cjs.TimeSelector, { format: timeFormat, disabled }),
|
|
22
|
+
type === "weekly" && /* @__PURE__ */ jsxRuntime.jsx(chunkWU6ZLOL4_cjs.DayChips, { disabled, showPresets: true }),
|
|
23
|
+
type === "monthly" && /* @__PURE__ */ jsxRuntime.jsx(chunkWU6ZLOL4_cjs.MonthDayGrid, { disabled, showPresets: true }),
|
|
24
|
+
type === "custom" && /* @__PURE__ */ jsxRuntime.jsx(chunkWU6ZLOL4_cjs.CustomInput, { disabled }),
|
|
25
25
|
showPreview && /* @__PURE__ */ jsxRuntime.jsx(
|
|
26
|
-
|
|
26
|
+
chunkWU6ZLOL4_cjs.SchedulePreview,
|
|
27
27
|
{
|
|
28
28
|
showCronExpression: true,
|
|
29
29
|
allowCopy
|
|
@@ -44,7 +44,7 @@ function CronScheduler({
|
|
|
44
44
|
className
|
|
45
45
|
}) {
|
|
46
46
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
47
|
-
|
|
47
|
+
chunkWU6ZLOL4_cjs.CronSchedulerProvider,
|
|
48
48
|
{
|
|
49
49
|
value,
|
|
50
50
|
onChange,
|
|
@@ -68,5 +68,5 @@ var CronScheduler_client_default = CronScheduler;
|
|
|
68
68
|
|
|
69
69
|
exports.CronScheduler = CronScheduler;
|
|
70
70
|
exports.default = CronScheduler_client_default;
|
|
71
|
-
//# sourceMappingURL=CronScheduler.client-
|
|
72
|
-
//# sourceMappingURL=CronScheduler.client-
|
|
71
|
+
//# sourceMappingURL=CronScheduler.client-Q6HLKGLR.cjs.map
|
|
72
|
+
//# sourceMappingURL=CronScheduler.client-Q6HLKGLR.cjs.map
|
package/dist/{CronScheduler.client-X74RLZLW.cjs.map → CronScheduler.client-Q6HLKGLR.cjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/CronScheduler/CronScheduler.client.tsx"],"names":["useCronType","cn","jsx","ScheduleTypeSelector","TimeSelector","DayChips","MonthDayGrid","CustomInput","SchedulePreview","__name","CronSchedulerProvider"],"mappings":";;;;;;;;;AAmCA,SAAS,kBAAA,CAAmB;AAAA,EAC1B,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAA4B;AAC1B,EAAA,MAAM,EAAE,IAAA,EAAK,GAAIA,6BAAA,EAAY;AAE7B,EAAA,uCACG,KAAA,EAAA,EAAI,SAAA,EAAWC,MAAA,CAAG,WAAA,EAAa,SAAS,CAAA,EAEvC,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAACC,0CAAqB,QAAA,EAAoB,CAAA;AAAA,IAGzC,SAAS,QAAA,oBACRD,cAAA,CAACE,8BAAA,EAAA,EAAa,MAAA,EAAQ,YAAY,QAAA,EAAoB,CAAA;AAAA,IAIvD,SAAS,QAAA,oBACRF,cAAA,CAACG,0BAAA,EAAA,EAAS,QAAA,EAAoB,aAAW,IAAA,EAAC,CAAA;AAAA,IAI3C,SAAS,SAAA,oBACRH,cAAA,CAACI,8BAAA,EAAA,EAAa,QAAA,EAAoB,aAAW,IAAA,EAAC,CAAA;AAAA,IAI/C,IAAA,KAAS,QAAA,oBACRJ,cAAA,CAACK,6BAAA,EAAA,EAAY,QAAA,EAAoB,CAAA;AAAA,IAIlC,WAAA,oBACCL,cAAA;AAAA,MAACM,iCAAA;AAAA,MAAA;AAAA,QACC,kBAAA,EAAkB,IAAA;AAAA,QAClB;AAAA;AAAA;AACF,GAAA,EAEJ,CAAA;AAEJ;AA5CSC,wBAAA,CAAA,kBAAA,EAAA,oBAAA,CAAA;AA2EF,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,WAAA,GAAc,IAAA;AAAA,EACd,kBAAA,GAAqB,KAAA;AAAA,EACrB,SAAA,GAAY,KAAA;AAAA,EACZ,UAAA,GAAa,KAAA;AAAA,EACb,QAAA,GAAW,KAAA;AAAA,EACX;AACF,CAAA,EAAuB;AACrB,EAAA,uBACEP,cAAA;AAAA,IAACQ,uCAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,QAAA;AAAA,MACA,WAAA;AAAA,MAEA,QAAA,kBAAAR,cAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,WAAA;AAAA,UACA,kBAAA;AAAA,UACA,SAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;AA3BgBO,wBAAA,CAAA,aAAA,EAAA,eAAA,CAAA;AA6BhB,IAAO,4BAAA,GAAQ","file":"CronScheduler.client-
|
|
1
|
+
{"version":3,"sources":["../src/tools/CronScheduler/CronScheduler.client.tsx"],"names":["useCronType","cn","jsx","ScheduleTypeSelector","TimeSelector","DayChips","MonthDayGrid","CustomInput","SchedulePreview","__name","CronSchedulerProvider"],"mappings":";;;;;;;;;AAmCA,SAAS,kBAAA,CAAmB;AAAA,EAC1B,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAA4B;AAC1B,EAAA,MAAM,EAAE,IAAA,EAAK,GAAIA,6BAAA,EAAY;AAE7B,EAAA,uCACG,KAAA,EAAA,EAAI,SAAA,EAAWC,MAAA,CAAG,WAAA,EAAa,SAAS,CAAA,EAEvC,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAACC,0CAAqB,QAAA,EAAoB,CAAA;AAAA,IAGzC,SAAS,QAAA,oBACRD,cAAA,CAACE,8BAAA,EAAA,EAAa,MAAA,EAAQ,YAAY,QAAA,EAAoB,CAAA;AAAA,IAIvD,SAAS,QAAA,oBACRF,cAAA,CAACG,0BAAA,EAAA,EAAS,QAAA,EAAoB,aAAW,IAAA,EAAC,CAAA;AAAA,IAI3C,SAAS,SAAA,oBACRH,cAAA,CAACI,8BAAA,EAAA,EAAa,QAAA,EAAoB,aAAW,IAAA,EAAC,CAAA;AAAA,IAI/C,IAAA,KAAS,QAAA,oBACRJ,cAAA,CAACK,6BAAA,EAAA,EAAY,QAAA,EAAoB,CAAA;AAAA,IAIlC,WAAA,oBACCL,cAAA;AAAA,MAACM,iCAAA;AAAA,MAAA;AAAA,QACC,kBAAA,EAAkB,IAAA;AAAA,QAClB;AAAA;AAAA;AACF,GAAA,EAEJ,CAAA;AAEJ;AA5CSC,wBAAA,CAAA,kBAAA,EAAA,oBAAA,CAAA;AA2EF,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,WAAA,GAAc,IAAA;AAAA,EACd,kBAAA,GAAqB,KAAA;AAAA,EACrB,SAAA,GAAY,KAAA;AAAA,EACZ,UAAA,GAAa,KAAA;AAAA,EACb,QAAA,GAAW,KAAA;AAAA,EACX;AACF,CAAA,EAAuB;AACrB,EAAA,uBACEP,cAAA;AAAA,IAACQ,uCAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,QAAA;AAAA,MACA,WAAA;AAAA,MAEA,QAAA,kBAAAR,cAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,WAAA;AAAA,UACA,kBAAA;AAAA,UACA,SAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;AA3BgBO,wBAAA,CAAA,aAAA,EAAA,eAAA,CAAA;AA6BhB,IAAO,4BAAA,GAAQ","file":"CronScheduler.client-Q6HLKGLR.cjs","sourcesContent":["'use client';\n\n/**\n * CronScheduler Client Component\n *\n * Compact cron expression builder following Apple HIG principles.\n * Uses context-based architecture for state management.\n */\n\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { CronSchedulerProvider } from './context/CronSchedulerContext';\nimport { useCronType } from './context/hooks';\nimport {\n ScheduleTypeSelector,\n TimeSelector,\n DayChips,\n MonthDayGrid,\n CustomInput,\n SchedulePreview,\n} from './components';\nimport type { CronSchedulerProps } from './types';\n\n// ============================================================================\n// Inner Component (uses context)\n// ============================================================================\n\ninterface CronSchedulerInnerProps {\n showPreview: boolean;\n showCronExpression: boolean;\n allowCopy: boolean;\n timeFormat: '12h' | '24h';\n disabled: boolean;\n className?: string;\n}\n\nfunction CronSchedulerInner({\n showPreview,\n showCronExpression,\n allowCopy,\n timeFormat,\n disabled,\n className,\n}: CronSchedulerInnerProps) {\n const { type } = useCronType();\n\n return (\n <div className={cn('space-y-3', className)}>\n {/* Schedule Type Selector */}\n <ScheduleTypeSelector disabled={disabled} />\n\n {/* Time Selector (shown for daily, weekly, monthly) */}\n {type !== 'custom' && (\n <TimeSelector format={timeFormat} disabled={disabled} />\n )}\n\n {/* Day Chips (weekly only) */}\n {type === 'weekly' && (\n <DayChips disabled={disabled} showPresets />\n )}\n\n {/* Month Day Grid (monthly only) */}\n {type === 'monthly' && (\n <MonthDayGrid disabled={disabled} showPresets />\n )}\n\n {/* Custom Input (custom only) */}\n {type === 'custom' && (\n <CustomInput disabled={disabled} />\n )}\n\n {/* Preview - always show cron expression */}\n {showPreview && (\n <SchedulePreview\n showCronExpression\n allowCopy={allowCopy}\n />\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Main Component (with Provider)\n// ============================================================================\n\n/**\n * CronScheduler - Compact cron expression builder\n *\n * A user-friendly interface for creating cron schedules without\n * needing to know cron syntax. Follows Apple HIG design principles.\n *\n * @example\n * // Basic usage\n * <CronScheduler\n * value={cronExpression}\n * onChange={setCronExpression}\n * />\n *\n * @example\n * // With all options\n * <CronScheduler\n * value=\"0 9 * * 1-5\"\n * onChange={handleChange}\n * defaultType=\"weekly\"\n * showPreview\n * showCronExpression\n * allowCopy\n * timeFormat=\"24h\"\n * />\n */\nexport function CronScheduler({\n value,\n onChange,\n defaultType = 'daily',\n showPreview = true,\n showCronExpression = false,\n allowCopy = false,\n timeFormat = '24h',\n disabled = false,\n className,\n}: CronSchedulerProps) {\n return (\n <CronSchedulerProvider\n value={value}\n onChange={onChange}\n defaultType={defaultType}\n >\n <CronSchedulerInner\n showPreview={showPreview}\n showCronExpression={showCronExpression}\n allowCopy={allowCopy}\n timeFormat={timeFormat}\n disabled={disabled}\n className={className}\n />\n </CronSchedulerProvider>\n );\n}\n\nexport default CronScheduler;\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCronType, ScheduleTypeSelector, TimeSelector, DayChips, MonthDayGrid, CustomInput, SchedulePreview, CronSchedulerProvider } from './chunk-
|
|
1
|
+
import { useCronType, ScheduleTypeSelector, TimeSelector, DayChips, MonthDayGrid, CustomInput, SchedulePreview, CronSchedulerProvider } from './chunk-7H4LDBIH.mjs';
|
|
2
2
|
import { __name } from './chunk-CGILA3WO.mjs';
|
|
3
3
|
import { cn } from '@djangocfg/ui-core/lib';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -63,5 +63,5 @@ __name(CronScheduler, "CronScheduler");
|
|
|
63
63
|
var CronScheduler_client_default = CronScheduler;
|
|
64
64
|
|
|
65
65
|
export { CronScheduler, CronScheduler_client_default as default };
|
|
66
|
-
//# sourceMappingURL=CronScheduler.client-
|
|
67
|
-
//# sourceMappingURL=CronScheduler.client-
|
|
66
|
+
//# sourceMappingURL=CronScheduler.client-T42ZXXOG.mjs.map
|
|
67
|
+
//# sourceMappingURL=CronScheduler.client-T42ZXXOG.mjs.map
|
package/dist/{CronScheduler.client-BYKMIOZJ.mjs.map → CronScheduler.client-T42ZXXOG.mjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/CronScheduler/CronScheduler.client.tsx"],"names":[],"mappings":";;;;;AAmCA,SAAS,kBAAA,CAAmB;AAAA,EAC1B,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAA4B;AAC1B,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,WAAA,EAAY;AAE7B,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,WAAA,EAAa,SAAS,CAAA,EAEvC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,wBAAqB,QAAA,EAAoB,CAAA;AAAA,IAGzC,SAAS,QAAA,oBACR,GAAA,CAAC,YAAA,EAAA,EAAa,MAAA,EAAQ,YAAY,QAAA,EAAoB,CAAA;AAAA,IAIvD,SAAS,QAAA,oBACR,GAAA,CAAC,QAAA,EAAA,EAAS,QAAA,EAAoB,aAAW,IAAA,EAAC,CAAA;AAAA,IAI3C,SAAS,SAAA,oBACR,GAAA,CAAC,YAAA,EAAA,EAAa,QAAA,EAAoB,aAAW,IAAA,EAAC,CAAA;AAAA,IAI/C,IAAA,KAAS,QAAA,oBACR,GAAA,CAAC,WAAA,EAAA,EAAY,QAAA,EAAoB,CAAA;AAAA,IAIlC,WAAA,oBACC,GAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,kBAAA,EAAkB,IAAA;AAAA,QAClB;AAAA;AAAA;AACF,GAAA,EAEJ,CAAA;AAEJ;AA5CS,MAAA,CAAA,kBAAA,EAAA,oBAAA,CAAA;AA2EF,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,WAAA,GAAc,IAAA;AAAA,EACd,kBAAA,GAAqB,KAAA;AAAA,EACrB,SAAA,GAAY,KAAA;AAAA,EACZ,UAAA,GAAa,KAAA;AAAA,EACb,QAAA,GAAW,KAAA;AAAA,EACX;AACF,CAAA,EAAuB;AACrB,EAAA,uBACE,GAAA;AAAA,IAAC,qBAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,QAAA;AAAA,MACA,WAAA;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,WAAA;AAAA,UACA,kBAAA;AAAA,UACA,SAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;AA3BgB,MAAA,CAAA,aAAA,EAAA,eAAA,CAAA;AA6BhB,IAAO,4BAAA,GAAQ","file":"CronScheduler.client-
|
|
1
|
+
{"version":3,"sources":["../src/tools/CronScheduler/CronScheduler.client.tsx"],"names":[],"mappings":";;;;;AAmCA,SAAS,kBAAA,CAAmB;AAAA,EAC1B,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAA4B;AAC1B,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,WAAA,EAAY;AAE7B,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,WAAA,EAAa,SAAS,CAAA,EAEvC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,wBAAqB,QAAA,EAAoB,CAAA;AAAA,IAGzC,SAAS,QAAA,oBACR,GAAA,CAAC,YAAA,EAAA,EAAa,MAAA,EAAQ,YAAY,QAAA,EAAoB,CAAA;AAAA,IAIvD,SAAS,QAAA,oBACR,GAAA,CAAC,QAAA,EAAA,EAAS,QAAA,EAAoB,aAAW,IAAA,EAAC,CAAA;AAAA,IAI3C,SAAS,SAAA,oBACR,GAAA,CAAC,YAAA,EAAA,EAAa,QAAA,EAAoB,aAAW,IAAA,EAAC,CAAA;AAAA,IAI/C,IAAA,KAAS,QAAA,oBACR,GAAA,CAAC,WAAA,EAAA,EAAY,QAAA,EAAoB,CAAA;AAAA,IAIlC,WAAA,oBACC,GAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,kBAAA,EAAkB,IAAA;AAAA,QAClB;AAAA;AAAA;AACF,GAAA,EAEJ,CAAA;AAEJ;AA5CS,MAAA,CAAA,kBAAA,EAAA,oBAAA,CAAA;AA2EF,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,WAAA,GAAc,IAAA;AAAA,EACd,kBAAA,GAAqB,KAAA;AAAA,EACrB,SAAA,GAAY,KAAA;AAAA,EACZ,UAAA,GAAa,KAAA;AAAA,EACb,QAAA,GAAW,KAAA;AAAA,EACX;AACF,CAAA,EAAuB;AACrB,EAAA,uBACE,GAAA;AAAA,IAAC,qBAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,QAAA;AAAA,MACA,WAAA;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,WAAA;AAAA,UACA,kBAAA;AAAA,UACA,SAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;AA3BgB,MAAA,CAAA,aAAA,EAAA,eAAA,CAAA;AA6BhB,IAAO,4BAAA,GAAQ","file":"CronScheduler.client-T42ZXXOG.mjs","sourcesContent":["'use client';\n\n/**\n * CronScheduler Client Component\n *\n * Compact cron expression builder following Apple HIG principles.\n * Uses context-based architecture for state management.\n */\n\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { CronSchedulerProvider } from './context/CronSchedulerContext';\nimport { useCronType } from './context/hooks';\nimport {\n ScheduleTypeSelector,\n TimeSelector,\n DayChips,\n MonthDayGrid,\n CustomInput,\n SchedulePreview,\n} from './components';\nimport type { CronSchedulerProps } from './types';\n\n// ============================================================================\n// Inner Component (uses context)\n// ============================================================================\n\ninterface CronSchedulerInnerProps {\n showPreview: boolean;\n showCronExpression: boolean;\n allowCopy: boolean;\n timeFormat: '12h' | '24h';\n disabled: boolean;\n className?: string;\n}\n\nfunction CronSchedulerInner({\n showPreview,\n showCronExpression,\n allowCopy,\n timeFormat,\n disabled,\n className,\n}: CronSchedulerInnerProps) {\n const { type } = useCronType();\n\n return (\n <div className={cn('space-y-3', className)}>\n {/* Schedule Type Selector */}\n <ScheduleTypeSelector disabled={disabled} />\n\n {/* Time Selector (shown for daily, weekly, monthly) */}\n {type !== 'custom' && (\n <TimeSelector format={timeFormat} disabled={disabled} />\n )}\n\n {/* Day Chips (weekly only) */}\n {type === 'weekly' && (\n <DayChips disabled={disabled} showPresets />\n )}\n\n {/* Month Day Grid (monthly only) */}\n {type === 'monthly' && (\n <MonthDayGrid disabled={disabled} showPresets />\n )}\n\n {/* Custom Input (custom only) */}\n {type === 'custom' && (\n <CustomInput disabled={disabled} />\n )}\n\n {/* Preview - always show cron expression */}\n {showPreview && (\n <SchedulePreview\n showCronExpression\n allowCopy={allowCopy}\n />\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Main Component (with Provider)\n// ============================================================================\n\n/**\n * CronScheduler - Compact cron expression builder\n *\n * A user-friendly interface for creating cron schedules without\n * needing to know cron syntax. Follows Apple HIG design principles.\n *\n * @example\n * // Basic usage\n * <CronScheduler\n * value={cronExpression}\n * onChange={setCronExpression}\n * />\n *\n * @example\n * // With all options\n * <CronScheduler\n * value=\"0 9 * * 1-5\"\n * onChange={handleChange}\n * defaultType=\"weekly\"\n * showPreview\n * showCronExpression\n * allowCopy\n * timeFormat=\"24h\"\n * />\n */\nexport function CronScheduler({\n value,\n onChange,\n defaultType = 'daily',\n showPreview = true,\n showCronExpression = false,\n allowCopy = false,\n timeFormat = '24h',\n disabled = false,\n className,\n}: CronSchedulerProps) {\n return (\n <CronSchedulerProvider\n value={value}\n onChange={onChange}\n defaultType={defaultType}\n >\n <CronSchedulerInner\n showPreview={showPreview}\n showCronExpression={showCronExpression}\n allowCopy={allowCopy}\n timeFormat={timeFormat}\n disabled={disabled}\n className={className}\n />\n </CronSchedulerProvider>\n );\n}\n\nexport default CronScheduler;\n"]}
|
|
@@ -7,24 +7,29 @@ import { Clock, CheckCircle2, AlertCircle, HelpCircle, Calendar, Check, Copy } f
|
|
|
7
7
|
|
|
8
8
|
// src/tools/CronScheduler/utils/cron-builder.ts
|
|
9
9
|
function buildCron(state) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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 : [];
|
|
13
18
|
switch (type) {
|
|
14
19
|
case "daily":
|
|
15
20
|
return `${m} ${h} * * *`;
|
|
16
21
|
case "weekly": {
|
|
17
|
-
const sortedDays = [...
|
|
22
|
+
const sortedDays = [...safeWeekDays].sort((a, b) => a - b);
|
|
18
23
|
const daysStr = sortedDays.length > 0 ? formatNumberList(sortedDays) : "*";
|
|
19
24
|
return `${m} ${h} * * ${daysStr}`;
|
|
20
25
|
}
|
|
21
26
|
case "monthly": {
|
|
22
|
-
const sortedDays = [...
|
|
27
|
+
const sortedDays = [...safeMonthDays].sort((a, b) => a - b);
|
|
23
28
|
const daysStr = sortedDays.length > 0 ? formatNumberList(sortedDays) : "1";
|
|
24
29
|
return `${m} ${h} ${daysStr} * *`;
|
|
25
30
|
}
|
|
26
31
|
case "custom":
|
|
27
|
-
return customCron.trim() || "* * * * *";
|
|
32
|
+
return (customCron || "").trim() || "* * * * *";
|
|
28
33
|
default:
|
|
29
34
|
return "0 0 * * *";
|
|
30
35
|
}
|
|
@@ -57,10 +62,13 @@ function parseCron(cron) {
|
|
|
57
62
|
const parts = cron.trim().split(/\s+/);
|
|
58
63
|
if (parts.length !== 5) return null;
|
|
59
64
|
const [minutePart, hourPart, dayOfMonthPart, monthPart, dayOfWeekPart] = parts;
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
if (
|
|
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);
|
|
64
72
|
const result = detectScheduleType(
|
|
65
73
|
minutePart,
|
|
66
74
|
hourPart,
|
|
@@ -95,10 +103,31 @@ function detectScheduleType(_minutePart, _hourPart, dayOfMonthPart, monthPart, d
|
|
|
95
103
|
return { type, weekDays, monthDays };
|
|
96
104
|
}
|
|
97
105
|
__name(detectScheduleType, "detectScheduleType");
|
|
98
|
-
function
|
|
106
|
+
function isValidCronField(part, min, max) {
|
|
107
|
+
if (part === "*") return true;
|
|
108
|
+
if (part.includes("/")) {
|
|
109
|
+
const [base, step] = part.split("/");
|
|
110
|
+
if (!step || !/^\d+$/.test(step)) return false;
|
|
111
|
+
if (base === "*") return true;
|
|
112
|
+
return isValidCronField(base, min, max);
|
|
113
|
+
}
|
|
114
|
+
if (part.includes("-") && !part.includes(",")) {
|
|
115
|
+
const [start, end] = part.split("-").map((s) => parseInt(s, 10));
|
|
116
|
+
return !isNaN(start) && !isNaN(end) && start >= min && end <= max && start <= end;
|
|
117
|
+
}
|
|
118
|
+
if (part.includes(",")) {
|
|
119
|
+
return part.split(",").every((p) => isValidCronField(p.trim(), min, max));
|
|
120
|
+
}
|
|
99
121
|
if (/^\d+$/.test(part)) {
|
|
100
122
|
const num = parseInt(part, 10);
|
|
101
|
-
|
|
123
|
+
return num >= min && num <= max;
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
__name(isValidCronField, "isValidCronField");
|
|
128
|
+
function parseField(part, _min, _max) {
|
|
129
|
+
if (/^\d+$/.test(part)) {
|
|
130
|
+
return parseInt(part, 10);
|
|
102
131
|
}
|
|
103
132
|
return null;
|
|
104
133
|
}
|
|
@@ -147,19 +176,8 @@ function isValidCron(cron) {
|
|
|
147
176
|
if (!cron || typeof cron !== "string") return false;
|
|
148
177
|
const parts = cron.trim().split(/\s+/);
|
|
149
178
|
if (parts.length !== 5) return false;
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
// minute
|
|
153
|
-
/^(\*|\d{1,2}|\d{1,2}-\d{1,2}|\d{1,2}(,\d{1,2})*|\*\/\d{1,2})$/,
|
|
154
|
-
// hour
|
|
155
|
-
/^(\*|\d{1,2}|\d{1,2}-\d{1,2}|\d{1,2}(,\d{1,2})*|\*\/\d{1,2})$/,
|
|
156
|
-
// day of month
|
|
157
|
-
/^(\*|\d{1,2}|\d{1,2}-\d{1,2}|\d{1,2}(,\d{1,2})*|\*\/\d{1,2})$/,
|
|
158
|
-
// month
|
|
159
|
-
/^(\*|\d{1}|\d{1}-\d{1}|\d{1}(,\d{1})*|\*\/\d{1,2})$/
|
|
160
|
-
// day of week
|
|
161
|
-
];
|
|
162
|
-
return parts.every((part, i) => patterns[i].test(part));
|
|
179
|
+
const [minutePart, hourPart, dayOfMonthPart, monthPart, dayOfWeekPart] = parts;
|
|
180
|
+
return isValidCronField(minutePart, 0, 59) && isValidCronField(hourPart, 0, 23) && isValidCronField(dayOfMonthPart, 1, 31) && isValidCronField(monthPart, 1, 12) && isValidCronField(dayOfWeekPart, 0, 6);
|
|
163
181
|
}
|
|
164
182
|
__name(isValidCron, "isValidCron");
|
|
165
183
|
|
|
@@ -309,21 +327,27 @@ function CronSchedulerProvider({
|
|
|
309
327
|
const onChangeRef = useRef(onChange);
|
|
310
328
|
onChangeRef.current = onChange;
|
|
311
329
|
const [state, setState] = useState(() => {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
330
|
+
try {
|
|
331
|
+
if (value) {
|
|
332
|
+
const parsed = parseCron(value);
|
|
333
|
+
if (parsed) return parsed;
|
|
334
|
+
}
|
|
335
|
+
} catch {
|
|
315
336
|
}
|
|
316
337
|
return { ...DEFAULT_STATE, type: defaultType };
|
|
317
338
|
});
|
|
318
339
|
useEffect(() => {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
340
|
+
try {
|
|
341
|
+
if (value) {
|
|
342
|
+
const parsed = parseCron(value);
|
|
343
|
+
if (parsed) {
|
|
344
|
+
const currentCron = buildCron(state);
|
|
345
|
+
if (value !== currentCron) {
|
|
346
|
+
setState(parsed);
|
|
347
|
+
}
|
|
325
348
|
}
|
|
326
349
|
}
|
|
350
|
+
} catch {
|
|
327
351
|
}
|
|
328
352
|
}, [value]);
|
|
329
353
|
const cronExpression = useMemo(() => buildCron(state), [state]);
|
|
@@ -619,11 +643,12 @@ function DayChips({
|
|
|
619
643
|
className
|
|
620
644
|
}) {
|
|
621
645
|
const { weekDays, toggleWeekDay, setWeekDays } = useCronWeekDays();
|
|
622
|
-
const
|
|
623
|
-
const
|
|
624
|
-
const
|
|
646
|
+
const safeWeekDays = Array.isArray(weekDays) ? weekDays : [];
|
|
647
|
+
const isWeekdays2 = safeWeekDays.length === 5 && [1, 2, 3, 4, 5].every((d) => safeWeekDays.includes(d));
|
|
648
|
+
const isWeekendPreset = safeWeekDays.length === 2 && [0, 6].every((d) => safeWeekDays.includes(d));
|
|
649
|
+
const isEveryday = safeWeekDays.length === 7;
|
|
625
650
|
const dayButtons = DAYS.map(({ value, label }) => {
|
|
626
|
-
const isSelected =
|
|
651
|
+
const isSelected = safeWeekDays.includes(value);
|
|
627
652
|
const isWeekendDay = value === 0 || value === 6;
|
|
628
653
|
return {
|
|
629
654
|
value,
|
|
@@ -702,9 +727,10 @@ function MonthDayGrid({
|
|
|
702
727
|
className
|
|
703
728
|
}) {
|
|
704
729
|
const { monthDays, toggleMonthDay, setMonthDays } = useCronMonthDays();
|
|
705
|
-
const
|
|
706
|
-
const
|
|
707
|
-
const
|
|
730
|
+
const safeMonthDays = Array.isArray(monthDays) ? monthDays : [];
|
|
731
|
+
const is1st = safeMonthDays.length === 1 && safeMonthDays[0] === 1;
|
|
732
|
+
const is15th = safeMonthDays.length === 1 && safeMonthDays[0] === 15;
|
|
733
|
+
const is1stAnd15th = safeMonthDays.length === 2 && safeMonthDays.includes(1) && safeMonthDays.includes(15);
|
|
708
734
|
const presets = [
|
|
709
735
|
{ label: "1st", isActive: is1st, days: [1] },
|
|
710
736
|
{ label: "15th", isActive: is15th, days: [15] },
|
|
@@ -713,7 +739,7 @@ function MonthDayGrid({
|
|
|
713
739
|
const gridCells = Array.from({ length: GRID_SIZE }, (_, i) => {
|
|
714
740
|
const day = i + 1;
|
|
715
741
|
const isValidDay = day <= 31;
|
|
716
|
-
const isSelected = isValidDay &&
|
|
742
|
+
const isSelected = isValidDay && safeMonthDays.includes(day);
|
|
717
743
|
const isPartialMonth = day > 28;
|
|
718
744
|
if (!isValidDay) {
|
|
719
745
|
return { type: "empty", key: i };
|
|
@@ -737,7 +763,7 @@ function MonthDayGrid({
|
|
|
737
763
|
)
|
|
738
764
|
};
|
|
739
765
|
});
|
|
740
|
-
const selectionCount =
|
|
766
|
+
const selectionCount = safeMonthDays.length;
|
|
741
767
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-3", className), children: [
|
|
742
768
|
showPresets && /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: presets.map((preset) => /* @__PURE__ */ jsx(
|
|
743
769
|
PresetButton2,
|
|
@@ -990,5 +1016,5 @@ function SchedulePreview({
|
|
|
990
1016
|
__name(SchedulePreview, "SchedulePreview");
|
|
991
1017
|
|
|
992
1018
|
export { CronSchedulerProvider, CustomInput, DayChips, MonthDayGrid, SchedulePreview, ScheduleTypeSelector, TimeSelector, buildCron, humanizeCron, isValidCron, parseCron, useCronCustom, useCronMonthDays, useCronPreview, useCronScheduler, useCronSchedulerContext, useCronTime, useCronType, useCronWeekDays };
|
|
993
|
-
//# sourceMappingURL=chunk-
|
|
994
|
-
//# sourceMappingURL=chunk-
|
|
1019
|
+
//# sourceMappingURL=chunk-7H4LDBIH.mjs.map
|
|
1020
|
+
//# sourceMappingURL=chunk-7H4LDBIH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools/CronScheduler/utils/cron-builder.ts","../src/tools/CronScheduler/utils/cron-parser.ts","../src/tools/CronScheduler/utils/cron-humanize.ts","../src/tools/CronScheduler/context/CronSchedulerContext.tsx","../src/tools/CronScheduler/context/hooks.ts","../src/tools/CronScheduler/components/ScheduleTypeSelector.tsx","../src/tools/CronScheduler/components/TimeSelector.tsx","../src/tools/CronScheduler/components/DayChips.tsx","../src/tools/CronScheduler/components/MonthDayGrid.tsx","../src/tools/CronScheduler/components/CustomInput.tsx","../src/tools/CronScheduler/components/CronCheatsheet.tsx","../src/tools/CronScheduler/components/SchedulePreview.tsx"],"names":["parseWeekDays","parseMonthDays","useMemo","jsx","cn","isWeekdays","jsxs","PresetButton","useState","useEffect","useCallback"],"mappings":"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","file":"chunk-7H4LDBIH.mjs","sourcesContent":["/**\n * Cron Builder\n *\n * Converts CronSchedulerState to Unix 5-field cron expression\n * Format: minute hour day-of-month month day-of-week\n */\n\nimport type { CronSchedulerState } from '../types';\n\n/**\n * Builds Unix 5-field cron expression from state\n *\n * @example\n * // Daily at 9:00\n * buildCron({ type: 'daily', hour: 9, minute: 0, ... }) // '0 9 * * *'\n *\n * // Weekly on Mon, Wed, Fri at 14:30\n * buildCron({ type: 'weekly', hour: 14, minute: 30, weekDays: [1, 3, 5], ... }) // '30 14 * * 1,3,5'\n *\n * // Monthly on 1st and 15th at 0:00\n * buildCron({ type: 'monthly', hour: 0, minute: 0, monthDays: [1, 15], ... }) // '0 0 1,15 * *'\n */\nexport function buildCron(state: CronSchedulerState): string {\n // Guard against invalid state\n if (!state || typeof state !== 'object') {\n return '0 0 * * *';\n }\n\n const { type, hour = 0, minute = 0, weekDays = [], monthDays = [], customCron = '' } = state;\n\n // Ensure valid hour/minute\n const h = Math.max(0, Math.min(23, Number(hour) || 0));\n const m = Math.max(0, Math.min(59, Number(minute) || 0));\n\n // Ensure arrays\n const safeWeekDays = Array.isArray(weekDays) ? weekDays : [];\n const safeMonthDays = Array.isArray(monthDays) ? monthDays : [];\n\n switch (type) {\n case 'daily':\n // Run every day at specified time\n return `${m} ${h} * * *`;\n\n case 'weekly': {\n // Run on specified days of week at specified time\n const sortedDays = [...safeWeekDays].sort((a, b) => a - b);\n const daysStr = sortedDays.length > 0 ? formatNumberList(sortedDays) : '*';\n return `${m} ${h} * * ${daysStr}`;\n }\n\n case 'monthly': {\n // Run on specified days of month at specified time\n const sortedDays = [...safeMonthDays].sort((a, b) => a - b);\n const daysStr = sortedDays.length > 0 ? formatNumberList(sortedDays) : '1';\n return `${m} ${h} ${daysStr} * *`;\n }\n\n case 'custom':\n // Return user-provided expression\n return (customCron || '').trim() || '* * * * *';\n\n default:\n return '0 0 * * *';\n }\n}\n\n/**\n * Formats a list of numbers as ranges where possible\n * [1,2,3,5,7,8,9] -> \"1-3,5,7-9\"\n */\nfunction formatNumberList(nums: number[]): string {\n if (nums.length === 0) return '';\n if (nums.length === 1) return nums[0].toString();\n\n const sorted = [...nums].sort((a, b) => a - b);\n const ranges: string[] = [];\n let start = sorted[0];\n let end = sorted[0];\n\n for (let i = 1; i < sorted.length; i++) {\n if (sorted[i] === end + 1) {\n // Continue the range\n end = sorted[i];\n } else {\n // End current range, start new one\n ranges.push(start === end ? `${start}` : `${start}-${end}`);\n start = sorted[i];\n end = sorted[i];\n }\n }\n\n // Don't forget the last range\n ranges.push(start === end ? `${start}` : `${start}-${end}`);\n\n return ranges.join(',');\n}\n\n/**\n * Builds cron for a specific schedule type with defaults\n */\nexport function buildDefaultCron(type: CronSchedulerState['type']): string {\n const defaults: Record<typeof type, string> = {\n daily: '0 9 * * *', // Every day at 9:00\n weekly: '0 9 * * 1-5', // Weekdays at 9:00\n monthly: '0 9 1 * *', // 1st of month at 9:00\n custom: '* * * * *', // Every minute\n };\n return defaults[type];\n}\n","/**\n * Cron Parser\n *\n * Parses Unix 5-field cron expression into CronSchedulerState\n * Format: minute hour day-of-month month day-of-week\n */\n\nimport type { CronSchedulerState, ScheduleType, WeekDay, MonthDay } from '../types';\n\n/**\n * Parses Unix 5-field cron expression into state\n *\n * @param cron - Cron expression to parse\n * @returns Parsed state or null if invalid\n *\n * @example\n * parseCron('0 9 * * *')\n * // { type: 'daily', hour: 9, minute: 0, ... }\n *\n * parseCron('30 14 * * 1,3,5')\n * // { type: 'weekly', hour: 14, minute: 30, weekDays: [1, 3, 5], ... }\n */\nexport function parseCron(cron: string): CronSchedulerState | null {\n if (!cron || typeof cron !== 'string') return null;\n\n const parts = cron.trim().split(/\\s+/);\n\n // Unix cron has exactly 5 fields\n if (parts.length !== 5) return null;\n\n const [minutePart, hourPart, dayOfMonthPart, monthPart, dayOfWeekPart] = parts;\n\n // Validate all fields have valid cron syntax\n if (!isValidCronField(minutePart, 0, 59)) return null;\n if (!isValidCronField(hourPart, 0, 23)) return null;\n if (!isValidCronField(dayOfMonthPart, 1, 31)) return null;\n if (!isValidCronField(monthPart, 1, 12)) return null;\n if (!isValidCronField(dayOfWeekPart, 0, 6)) return null;\n\n // Parse simple numeric values for hour/minute (for UI state)\n const minute = parseField(minutePart, 0, 59);\n const hour = parseField(hourPart, 0, 23);\n\n // Determine schedule type based on field patterns\n const result = detectScheduleType(\n minutePart,\n hourPart,\n dayOfMonthPart,\n monthPart,\n dayOfWeekPart\n );\n\n return {\n type: result.type,\n hour: hour ?? 0,\n minute: minute ?? 0,\n weekDays: result.weekDays,\n monthDays: result.monthDays,\n customCron: cron,\n isValid: true,\n };\n}\n\n/**\n * Detects schedule type from cron fields\n */\nfunction detectScheduleType(\n _minutePart: string,\n _hourPart: string,\n dayOfMonthPart: string,\n monthPart: string,\n dayOfWeekPart: string\n): {\n type: ScheduleType;\n weekDays: WeekDay[];\n monthDays: MonthDay[];\n} {\n // Default values\n let type: ScheduleType = 'custom';\n let weekDays: WeekDay[] = [1, 2, 3, 4, 5]; // Mon-Fri\n let monthDays: MonthDay[] = [1];\n\n // Daily: M H * * *\n if (dayOfMonthPart === '*' && monthPart === '*' && dayOfWeekPart === '*') {\n type = 'daily';\n }\n // Weekly: M H * * 1,2,3 (or ranges like 1-5)\n else if (dayOfMonthPart === '*' && monthPart === '*' && dayOfWeekPart !== '*') {\n type = 'weekly';\n weekDays = parseWeekDays(dayOfWeekPart);\n }\n // Monthly: M H 1,15 * * (day-of-month specified)\n else if (dayOfMonthPart !== '*' && monthPart === '*' && dayOfWeekPart === '*') {\n type = 'monthly';\n monthDays = parseMonthDays(dayOfMonthPart);\n }\n // Everything else is custom\n\n return { type, weekDays, monthDays };\n}\n\n/**\n * Validates a cron field has valid syntax\n * Supports: asterisk, number, range (1-5), list (1,3,5), step (star/15, 1-5/2)\n */\nfunction isValidCronField(part: string, min: number, max: number): boolean {\n if (part === '*') return true;\n\n // Step pattern: */N or range/N\n if (part.includes('/')) {\n const [base, step] = part.split('/');\n if (!step || !/^\\d+$/.test(step)) return false;\n if (base === '*') return true;\n // Validate base part (range or number)\n return isValidCronField(base, min, max);\n }\n\n // Range pattern: N-M\n if (part.includes('-') && !part.includes(',')) {\n const [start, end] = part.split('-').map(s => parseInt(s, 10));\n return !isNaN(start) && !isNaN(end) && start >= min && end <= max && start <= end;\n }\n\n // List pattern: N,M,O\n if (part.includes(',')) {\n return part.split(',').every(p => isValidCronField(p.trim(), min, max));\n }\n\n // Simple number\n if (/^\\d+$/.test(part)) {\n const num = parseInt(part, 10);\n return num >= min && num <= max;\n }\n\n return false;\n}\n\n/**\n * Parses a single numeric field (simple number only)\n */\nfunction parseField(part: string, _min: number, _max: number): number | null {\n if (/^\\d+$/.test(part)) {\n return parseInt(part, 10);\n }\n return null;\n}\n\n/**\n * Parses week days from cron field\n * Supports: 1,2,3 or 1-5 or MON,WED,FRI\n */\nfunction parseWeekDays(part: string): WeekDay[] {\n const result: WeekDay[] = [];\n\n // Handle ranges like 1-5\n if (part.includes('-')) {\n const [start, end] = part.split('-').map(s => parseInt(s, 10));\n if (!isNaN(start) && !isNaN(end)) {\n for (let i = start; i <= end && i <= 6; i++) {\n if (i >= 0) result.push(i as WeekDay);\n }\n }\n return result.length > 0 ? result : [1, 2, 3, 4, 5];\n }\n\n // Handle comma-separated list\n for (const segment of part.split(',')) {\n const num = parseInt(segment.trim(), 10);\n if (!isNaN(num) && num >= 0 && num <= 6) {\n result.push(num as WeekDay);\n }\n }\n\n return result.length > 0 ? result : [1, 2, 3, 4, 5];\n}\n\n/**\n * Parses month days from cron field\n * Supports: 1,15 or 1-15\n */\nfunction parseMonthDays(part: string): MonthDay[] {\n const result: MonthDay[] = [];\n\n // Handle ranges like 1-15\n if (part.includes('-')) {\n const [start, end] = part.split('-').map(s => parseInt(s, 10));\n if (!isNaN(start) && !isNaN(end)) {\n for (let i = start; i <= end && i <= 31; i++) {\n if (i >= 1) result.push(i as MonthDay);\n }\n }\n return result.length > 0 ? result : [1];\n }\n\n // Handle comma-separated list\n for (const segment of part.split(',')) {\n const num = parseInt(segment.trim(), 10);\n if (!isNaN(num) && num >= 1 && num <= 31) {\n result.push(num as MonthDay);\n }\n }\n\n return result.length > 0 ? result : [1];\n}\n\n/**\n * Validates cron expression syntax\n */\nexport function isValidCron(cron: string): boolean {\n if (!cron || typeof cron !== 'string') return false;\n\n const parts = cron.trim().split(/\\s+/);\n if (parts.length !== 5) return false;\n\n const [minutePart, hourPart, dayOfMonthPart, monthPart, dayOfWeekPart] = parts;\n\n return (\n isValidCronField(minutePart, 0, 59) &&\n isValidCronField(hourPart, 0, 23) &&\n isValidCronField(dayOfMonthPart, 1, 31) &&\n isValidCronField(monthPart, 1, 12) &&\n isValidCronField(dayOfWeekPart, 0, 6)\n );\n}\n","/**\n * Cron Humanize\n *\n * Converts cron expressions to human-readable descriptions\n */\n\nconst WEEKDAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\nconst WEEKDAY_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\n/**\n * Converts cron expression to human-readable description\n *\n * Examples:\n * - humanizeCron('0 9 * * *') returns \"Every day at 09:00\"\n * - humanizeCron('30 14 * * 1,3,5') returns \"Mon, Wed, Fri at 14:30\"\n * - humanizeCron('0 0 1 * *') returns \"1st of every month at 00:00\"\n */\nexport function humanizeCron(cron: string): string {\n if (!cron || typeof cron !== 'string') return 'Invalid schedule';\n\n const parts = cron.trim().split(/\\s+/);\n if (parts.length !== 5) return 'Invalid schedule';\n\n const [minutePart, hourPart, dayOfMonthPart, monthPart, dayOfWeekPart] = parts;\n\n // Parse time\n const minute = parseInt(minutePart, 10);\n const hour = parseInt(hourPart, 10);\n const timeStr = formatTime(hour, minute);\n\n // Every minute\n if (minutePart === '*' && hourPart === '*' && dayOfMonthPart === '*' && monthPart === '*' && dayOfWeekPart === '*') {\n return 'Every minute';\n }\n\n // Every N minutes\n if (minutePart.startsWith('*/')) {\n const interval = parseInt(minutePart.slice(2), 10);\n if (hourPart === '*') {\n return `Every ${interval} minute${interval > 1 ? 's' : ''}`;\n }\n return `Every ${interval} minute${interval > 1 ? 's' : ''} at hour ${hour}`;\n }\n\n // Hourly\n if (!isNaN(minute) && hourPart === '*' && dayOfMonthPart === '*' && monthPart === '*' && dayOfWeekPart === '*') {\n return `Every hour at minute ${minute}`;\n }\n\n // Daily\n if (dayOfMonthPart === '*' && monthPart === '*' && dayOfWeekPart === '*') {\n return `Every day at ${timeStr}`;\n }\n\n // Weekly\n if (dayOfMonthPart === '*' && monthPart === '*' && dayOfWeekPart !== '*') {\n const days = parseWeekDays(dayOfWeekPart);\n\n if (days.length === 7) {\n return `Every day at ${timeStr}`;\n }\n\n if (days.length === 5 && isWeekdays(days)) {\n return `Weekdays at ${timeStr}`;\n }\n\n if (days.length === 2 && isWeekend(days)) {\n return `Weekends at ${timeStr}`;\n }\n\n const dayNames = days.map(d => WEEKDAY_SHORT[d]).join(', ');\n return `${dayNames} at ${timeStr}`;\n }\n\n // Monthly\n if (dayOfMonthPart !== '*' && monthPart === '*' && dayOfWeekPart === '*') {\n const days = parseMonthDays(dayOfMonthPart);\n\n if (days.length === 1) {\n return `${ordinal(days[0])} of every month at ${timeStr}`;\n }\n\n if (days.length <= 3) {\n const dayStr = days.map(d => ordinal(d)).join(', ');\n return `${dayStr} of every month at ${timeStr}`;\n }\n\n return `${days.length} days per month at ${timeStr}`;\n }\n\n // Complex expression - show as-is\n return `Custom schedule`;\n}\n\n/**\n * Formats time as HH:MM\n */\nfunction formatTime(hour: number, minute: number): string {\n const h = isNaN(hour) ? 0 : Math.max(0, Math.min(23, hour));\n const m = isNaN(minute) ? 0 : Math.max(0, Math.min(59, minute));\n return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`;\n}\n\n/**\n * Formats time in 12-hour format with AM/PM\n */\nexport function formatTime12h(hour: number, minute: number): string {\n const h = isNaN(hour) ? 0 : Math.max(0, Math.min(23, hour));\n const m = isNaN(minute) ? 0 : Math.max(0, Math.min(59, minute));\n const period = h >= 12 ? 'PM' : 'AM';\n const h12 = h % 12 || 12;\n return `${h12}:${m.toString().padStart(2, '0')} ${period}`;\n}\n\n/**\n * Parses week days from cron field\n */\nfunction parseWeekDays(part: string): number[] {\n const result: number[] = [];\n\n // Handle ranges like 1-5\n if (part.includes('-') && !part.includes(',')) {\n const [start, end] = part.split('-').map(s => parseInt(s, 10));\n if (!isNaN(start) && !isNaN(end)) {\n for (let i = start; i <= end && i <= 6; i++) {\n if (i >= 0) result.push(i);\n }\n }\n return result;\n }\n\n // Handle comma-separated list\n for (const segment of part.split(',')) {\n // Handle nested ranges\n if (segment.includes('-')) {\n const [start, end] = segment.split('-').map(s => parseInt(s, 10));\n if (!isNaN(start) && !isNaN(end)) {\n for (let i = start; i <= end && i <= 6; i++) {\n if (i >= 0) result.push(i);\n }\n }\n } else {\n const num = parseInt(segment.trim(), 10);\n if (!isNaN(num) && num >= 0 && num <= 6) {\n result.push(num);\n }\n }\n }\n\n return result.sort((a, b) => a - b);\n}\n\n/**\n * Parses month days from cron field\n */\nfunction parseMonthDays(part: string): number[] {\n const result: number[] = [];\n\n // Handle ranges\n if (part.includes('-') && !part.includes(',')) {\n const [start, end] = part.split('-').map(s => parseInt(s, 10));\n if (!isNaN(start) && !isNaN(end)) {\n for (let i = start; i <= end && i <= 31; i++) {\n if (i >= 1) result.push(i);\n }\n }\n return result;\n }\n\n // Handle comma-separated list\n for (const segment of part.split(',')) {\n const num = parseInt(segment.trim(), 10);\n if (!isNaN(num) && num >= 1 && num <= 31) {\n result.push(num);\n }\n }\n\n return result.sort((a, b) => a - b);\n}\n\n/**\n * Checks if days array represents weekdays (Mon-Fri)\n */\nfunction isWeekdays(days: number[]): boolean {\n const sorted = [...days].sort((a, b) => a - b);\n return sorted.join(',') === '1,2,3,4,5';\n}\n\n/**\n * Checks if days array represents weekend (Sat-Sun)\n */\nfunction isWeekend(days: number[]): boolean {\n const sorted = [...days].sort((a, b) => a - b);\n return sorted.join(',') === '0,6';\n}\n\n/**\n * Returns ordinal suffix for a number (1st, 2nd, 3rd, etc.)\n */\nfunction ordinal(n: number): string {\n const s = ['th', 'st', 'nd', 'rd'];\n const v = n % 100;\n return n + (s[(v - 20) % 10] || s[v] || s[0]);\n}\n\n/**\n * Gets full weekday name\n */\nexport function getWeekdayName(day: number): string {\n return WEEKDAY_NAMES[day] || 'Unknown';\n}\n\n/**\n * Gets short weekday name\n */\nexport function getWeekdayShort(day: number): string {\n return WEEKDAY_SHORT[day] || '?';\n}\n","'use client';\n\n/**\n * CronScheduler Context\n *\n * Provides centralized state management for the CronScheduler component.\n * All child components subscribe to this context for state and actions.\n */\n\nimport {\n createContext,\n useContext,\n useMemo,\n useCallback,\n useState,\n useEffect,\n useRef,\n} from 'react';\nimport type {\n CronSchedulerContextValue,\n CronSchedulerState,\n CronSchedulerProviderProps,\n ScheduleType,\n WeekDay,\n MonthDay,\n} from '../types';\nimport { buildCron } from '../utils/cron-builder';\nimport { parseCron } from '../utils/cron-parser';\nimport { humanizeCron } from '../utils/cron-humanize';\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst CronSchedulerContext = createContext<CronSchedulerContextValue | null>(null);\n\n// ============================================================================\n// Default State\n// ============================================================================\n\nconst DEFAULT_STATE: CronSchedulerState = {\n type: 'daily',\n hour: 9,\n minute: 0,\n weekDays: [1, 2, 3, 4, 5] as WeekDay[], // Mon-Fri\n monthDays: [1] as MonthDay[],\n customCron: '* * * * *',\n isValid: true,\n};\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport function CronSchedulerProvider({\n children,\n value,\n onChange,\n defaultType = 'daily',\n}: CronSchedulerProviderProps) {\n // Track if this is initial mount to avoid calling onChange on mount\n const isInitialMount = useRef(true);\n\n // Store onChange in a ref to avoid triggering effects when it changes\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n // Initialize state from value prop or defaults\n const [state, setState] = useState<CronSchedulerState>(() => {\n try {\n if (value) {\n const parsed = parseCron(value);\n if (parsed) return parsed;\n }\n } catch {\n // Fallback to default on any parsing error\n }\n return { ...DEFAULT_STATE, type: defaultType };\n });\n\n // Sync with external value (controlled component support)\n useEffect(() => {\n try {\n if (value) {\n const parsed = parseCron(value);\n if (parsed) {\n const currentCron = buildCron(state);\n if (value !== currentCron) {\n setState(parsed);\n }\n }\n }\n } catch {\n // Ignore parsing errors, keep current state\n }\n }, [value]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Computed: cron expression\n const cronExpression = useMemo(() => buildCron(state), [state]);\n\n // Computed: human-readable description\n const humanDescription = useMemo(() => humanizeCron(cronExpression), [cronExpression]);\n\n // Notify parent on change (skip initial mount)\n // Use ref to avoid re-triggering when onChange identity changes\n useEffect(() => {\n if (isInitialMount.current) {\n isInitialMount.current = false;\n return;\n }\n onChangeRef.current?.(cronExpression);\n }, [cronExpression]);\n\n // ============================================================================\n // Actions\n // ============================================================================\n\n const setType = useCallback((type: ScheduleType) => {\n setState(s => ({ ...s, type }));\n }, []);\n\n const setTime = useCallback((hour: number, minute: number) => {\n setState(s => ({\n ...s,\n hour: Math.max(0, Math.min(23, hour)),\n minute: Math.max(0, Math.min(59, minute)),\n }));\n }, []);\n\n const toggleWeekDay = useCallback((day: WeekDay) => {\n setState(s => {\n const hasDay = s.weekDays.includes(day);\n // Prevent deselecting the last day\n if (hasDay && s.weekDays.length === 1) return s;\n\n const newDays = hasDay\n ? s.weekDays.filter(d => d !== day)\n : [...s.weekDays, day];\n\n return {\n ...s,\n weekDays: newDays.sort((a, b) => a - b) as WeekDay[],\n };\n });\n }, []);\n\n const setWeekDays = useCallback((days: WeekDay[]) => {\n setState(s => ({\n ...s,\n weekDays: days.length > 0\n ? [...days].sort((a, b) => a - b) as WeekDay[]\n : [1] as WeekDay[], // Default to Monday if empty\n }));\n }, []);\n\n const toggleMonthDay = useCallback((day: MonthDay) => {\n setState(s => {\n const hasDay = s.monthDays.includes(day);\n // Prevent deselecting the last day\n if (hasDay && s.monthDays.length === 1) return s;\n\n const newDays = hasDay\n ? s.monthDays.filter(d => d !== day)\n : [...s.monthDays, day];\n\n return {\n ...s,\n monthDays: newDays.sort((a, b) => a - b) as MonthDay[],\n };\n });\n }, []);\n\n const setMonthDays = useCallback((days: MonthDay[]) => {\n setState(s => ({\n ...s,\n monthDays: days.length > 0\n ? [...days].sort((a, b) => a - b) as MonthDay[]\n : [1] as MonthDay[], // Default to 1st if empty\n }));\n }, []);\n\n const setCustomCron = useCallback((customCron: string) => {\n const parsed = parseCron(customCron);\n setState(s => ({\n ...s,\n customCron,\n isValid: parsed !== null,\n }));\n }, []);\n\n const reset = useCallback(() => {\n setState({ ...DEFAULT_STATE, type: defaultType });\n }, [defaultType]);\n\n // ============================================================================\n // Context Value\n // ============================================================================\n\n const contextValue: CronSchedulerContextValue = useMemo(\n () => ({\n // State\n ...state,\n // Computed\n cronExpression,\n humanDescription,\n // Actions\n setType,\n setTime,\n toggleWeekDay,\n setWeekDays,\n toggleMonthDay,\n setMonthDays,\n setCustomCron,\n reset,\n }),\n [\n state,\n cronExpression,\n humanDescription,\n setType,\n setTime,\n toggleWeekDay,\n setWeekDays,\n toggleMonthDay,\n setMonthDays,\n setCustomCron,\n reset,\n ]\n );\n\n return (\n <CronSchedulerContext.Provider value={contextValue}>\n {children}\n </CronSchedulerContext.Provider>\n );\n}\n\n// ============================================================================\n// Context Hook\n// ============================================================================\n\nexport function useCronSchedulerContext(): CronSchedulerContextValue {\n const context = useContext(CronSchedulerContext);\n if (!context) {\n throw new Error(\n 'useCronSchedulerContext must be used within CronSchedulerProvider'\n );\n }\n return context;\n}\n","'use client';\n\n/**\n * CronScheduler Hooks\n *\n * Selective subscription hooks for optimal re-renders.\n * Each hook returns only the data it needs, preventing\n * unnecessary re-renders when unrelated state changes.\n */\n\nimport { useMemo } from 'react';\nimport { useCronSchedulerContext } from './CronSchedulerContext';\n\n/**\n * Hook for schedule type selection\n * Re-renders only when type changes\n */\nexport function useCronType() {\n const { type, setType } = useCronSchedulerContext();\n return useMemo(() => ({ type, setType }), [type, setType]);\n}\n\n/**\n * Hook for time selection\n * Re-renders only when hour/minute changes\n */\nexport function useCronTime() {\n const { hour, minute, setTime } = useCronSchedulerContext();\n return useMemo(() => ({ hour, minute, setTime }), [hour, minute, setTime]);\n}\n\n/**\n * Hook for week days selection\n * Re-renders only when weekDays changes\n */\nexport function useCronWeekDays() {\n const { weekDays, toggleWeekDay, setWeekDays } = useCronSchedulerContext();\n return useMemo(\n () => ({ weekDays, toggleWeekDay, setWeekDays }),\n [weekDays, toggleWeekDay, setWeekDays]\n );\n}\n\n/**\n * Hook for month days selection\n * Re-renders only when monthDays changes\n */\nexport function useCronMonthDays() {\n const { monthDays, toggleMonthDay, setMonthDays } = useCronSchedulerContext();\n return useMemo(\n () => ({ monthDays, toggleMonthDay, setMonthDays }),\n [monthDays, toggleMonthDay, setMonthDays]\n );\n}\n\n/**\n * Hook for custom cron input\n * Re-renders only when customCron/isValid changes\n */\nexport function useCronCustom() {\n const { customCron, isValid, setCustomCron } = useCronSchedulerContext();\n return useMemo(\n () => ({ customCron, isValid, setCustomCron }),\n [customCron, isValid, setCustomCron]\n );\n}\n\n/**\n * Hook for preview display\n * Re-renders only when computed values change\n */\nexport function useCronPreview() {\n const { cronExpression, humanDescription, isValid } = useCronSchedulerContext();\n return useMemo(\n () => ({ cronExpression, humanDescription, isValid }),\n [cronExpression, humanDescription, isValid]\n );\n}\n\n/**\n * Full context access\n * Use sparingly - causes re-render on any state change\n */\nexport function useCronScheduler() {\n return useCronSchedulerContext();\n}\n","'use client';\n\n/**\n * ScheduleTypeSelector\n *\n * Segmented control for selecting schedule type.\n * Uses Tabs from ui-core styled as a compact segmented control.\n */\n\nimport { Tabs, TabsList, TabsTrigger } from '@djangocfg/ui-core/components';\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { useCronType } from '../context/hooks';\nimport type { ScheduleType } from '../types';\n\nconst SCHEDULE_TYPES: { value: ScheduleType; label: string }[] = [\n { value: 'daily', label: 'Daily' },\n { value: 'weekly', label: 'Weekly' },\n { value: 'monthly', label: 'Monthly' },\n { value: 'custom', label: 'Custom' },\n];\n\nexport interface ScheduleTypeSelectorProps {\n disabled?: boolean;\n className?: string;\n}\n\nexport function ScheduleTypeSelector({\n disabled,\n className,\n}: ScheduleTypeSelectorProps) {\n const { type, setType } = useCronType();\n\n const triggerClassName = cn(\n 'text-xs font-medium px-2 py-1.5',\n 'data-[state=active]:shadow-sm',\n 'transition-all duration-150'\n );\n\n const triggers = SCHEDULE_TYPES.map(({ value, label }) => ({\n value,\n label,\n disabled,\n className: triggerClassName,\n }));\n\n return (\n <Tabs\n value={type}\n onValueChange={(v) => setType(v as ScheduleType)}\n className={cn('w-full', className)}\n >\n <TabsList className=\"grid w-full grid-cols-4 h-9 p-0.5\">\n {triggers.map((trigger) => (\n <TabsTrigger\n key={trigger.value}\n value={trigger.value}\n disabled={trigger.disabled}\n className={trigger.className}\n >\n {trigger.label}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n );\n}\n","'use client';\n\n/**\n * TimeSelector\n *\n * Clean time picker with hour and minute selects.\n */\n\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@djangocfg/ui-core/components';\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { Clock } from 'lucide-react';\nimport { useCronTime } from '../context/hooks';\n\nconst HOURS = Array.from({ length: 24 }, (_, i) => i);\nconst MINUTES = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55];\n\nexport interface TimeSelectorProps {\n format?: '12h' | '24h';\n disabled?: boolean;\n className?: string;\n}\n\nexport function TimeSelector({\n format = '24h',\n disabled,\n className,\n}: TimeSelectorProps) {\n const { hour, minute, setTime } = useCronTime();\n\n const is24h = format === '24h';\n const displayHour = is24h ? hour : (hour % 12) || 12;\n const isPM = hour >= 12;\n\n const handleHourChange = (value: string) => {\n let newHour = parseInt(value, 10);\n if (!is24h) {\n if (isPM && newHour !== 12) newHour += 12;\n else if (!isPM && newHour === 12) newHour = 0;\n }\n setTime(newHour, minute);\n };\n\n const handleMinuteChange = (value: string) => {\n setTime(hour, parseInt(value, 10));\n };\n\n const handlePeriodChange = (value: string) => {\n const newIsPM = value === 'PM';\n let newHour = hour;\n if (newIsPM && hour < 12) newHour = hour + 12;\n else if (!newIsPM && hour >= 12) newHour = hour - 12;\n setTime(newHour, minute);\n };\n\n const hours = is24h ? HOURS : Array.from({ length: 12 }, (_, i) => i + 1);\n\n return (\n <div className={cn('flex items-center gap-3', className)}>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Clock className=\"h-4 w-4\" />\n <span className=\"text-sm\">Run at</span>\n </div>\n\n <div className=\"flex items-center gap-1.5 flex-1\">\n {/* Hour */}\n <Select\n value={displayHour.toString()}\n onValueChange={handleHourChange}\n disabled={disabled}\n >\n <SelectTrigger className=\"w-[70px] h-9\">\n <SelectValue>\n {displayHour.toString().padStart(2, '0')}\n </SelectValue>\n </SelectTrigger>\n <SelectContent className=\"max-h-48\">\n {hours.map((h) => (\n <SelectItem key={h} value={h.toString()}>\n {h.toString().padStart(2, '0')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n <span className=\"text-muted-foreground font-medium\">:</span>\n\n {/* Minute */}\n <Select\n value={minute.toString()}\n onValueChange={handleMinuteChange}\n disabled={disabled}\n >\n <SelectTrigger className=\"w-[70px] h-9\">\n <SelectValue>\n {minute.toString().padStart(2, '0')}\n </SelectValue>\n </SelectTrigger>\n <SelectContent className=\"max-h-48\">\n {MINUTES.map((m) => (\n <SelectItem key={m} value={m.toString()}>\n {m.toString().padStart(2, '0')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {/* AM/PM for 12h */}\n {!is24h && (\n <Select\n value={isPM ? 'PM' : 'AM'}\n onValueChange={handlePeriodChange}\n disabled={disabled}\n >\n <SelectTrigger className=\"w-[70px] h-9\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"AM\">AM</SelectItem>\n <SelectItem value=\"PM\">PM</SelectItem>\n </SelectContent>\n </Select>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\n/**\n * DayChips\n *\n * Full-width day of week selector with clear labels.\n * Shows abbreviated day names for clarity.\n */\n\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { useCronWeekDays } from '../context/hooks';\nimport type { WeekDay } from '../types';\n\nconst DAYS: { value: WeekDay; label: string }[] = [\n { value: 1, label: 'Mon' },\n { value: 2, label: 'Tue' },\n { value: 3, label: 'Wed' },\n { value: 4, label: 'Thu' },\n { value: 5, label: 'Fri' },\n { value: 6, label: 'Sat' },\n { value: 0, label: 'Sun' },\n];\n\nexport interface DayChipsProps {\n disabled?: boolean;\n showPresets?: boolean;\n className?: string;\n}\n\nexport function DayChips({\n disabled,\n showPresets = true,\n className,\n}: DayChipsProps) {\n const { weekDays, toggleWeekDay, setWeekDays } = useCronWeekDays();\n\n // Ensure weekDays is always an array\n const safeWeekDays = Array.isArray(weekDays) ? weekDays : [];\n\n // Prepare data before render\n const isWeekdays = safeWeekDays.length === 5 && [1,2,3,4,5].every(d => safeWeekDays.includes(d as WeekDay));\n const isWeekendPreset = safeWeekDays.length === 2 && [0,6].every(d => safeWeekDays.includes(d as WeekDay));\n const isEveryday = safeWeekDays.length === 7;\n\n const dayButtons = DAYS.map(({ value, label }) => {\n const isSelected = safeWeekDays.includes(value);\n const isWeekendDay = value === 0 || value === 6;\n\n return {\n value,\n label,\n isSelected,\n isWeekendDay,\n className: cn(\n 'flex flex-col items-center justify-center',\n 'py-2.5 rounded-lg text-xs font-medium',\n 'transition-all duration-150',\n 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50',\n 'active:scale-[0.97]',\n isSelected\n ? 'bg-primary text-primary-foreground shadow-sm'\n : cn(\n 'bg-muted/50 hover:bg-muted',\n isWeekendDay ? 'text-muted-foreground/70' : 'text-muted-foreground'\n ),\n disabled && 'opacity-50 cursor-not-allowed pointer-events-none'\n ),\n };\n });\n\n const presets = [\n { label: 'Weekdays', isActive: isWeekdays, days: [1, 2, 3, 4, 5] as WeekDay[] },\n { label: 'Weekends', isActive: isWeekendPreset, days: [0, 6] as WeekDay[] },\n { label: 'Every day', isActive: isEveryday, days: [0, 1, 2, 3, 4, 5, 6] as WeekDay[] },\n ];\n\n return (\n <div className={cn('space-y-3', className)}>\n {/* Day Grid - full width */}\n <div className=\"grid grid-cols-7 gap-1\">\n {dayButtons.map((day) => (\n <button\n key={day.value}\n type=\"button\"\n disabled={disabled}\n onClick={() => toggleWeekDay(day.value)}\n aria-pressed={day.isSelected}\n className={day.className}\n >\n <span>{day.label}</span>\n </button>\n ))}\n </div>\n\n {/* Quick Presets */}\n {showPresets && (\n <div className=\"flex gap-2\">\n {presets.map((preset) => (\n <PresetButton\n key={preset.label}\n label={preset.label}\n isActive={preset.isActive}\n onClick={() => setWeekDays(preset.days)}\n disabled={disabled}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\ninterface PresetButtonProps {\n label: string;\n isActive: boolean;\n onClick: () => void;\n disabled?: boolean;\n}\n\nfunction PresetButton({ label, isActive, onClick, disabled }: PresetButtonProps) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onClick}\n className={cn(\n 'flex-1 px-3 py-1.5 rounded-md text-xs font-medium',\n 'transition-colors duration-150',\n 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50',\n isActive\n ? 'bg-primary/15 text-primary border border-primary/30'\n : 'bg-muted/30 text-muted-foreground hover:bg-muted/50 border border-transparent',\n disabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </button>\n );\n}\n","'use client';\n\n/**\n * MonthDayGrid\n *\n * Full-width calendar-style grid for selecting days of the month.\n * Clean, intuitive design like a mini calendar.\n */\n\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { useCronMonthDays } from '../context/hooks';\nimport type { MonthDay } from '../types';\n\n// Generate days 1-31\nconst DAYS: MonthDay[] = Array.from({ length: 31 }, (_, i) => (i + 1) as MonthDay);\n\n// Fill to complete last row (31 days = 4 full rows + 3 days, need 4 more to fill)\nconst GRID_SIZE = 35; // 5 rows x 7 columns\n\nexport interface MonthDayGridProps {\n disabled?: boolean;\n showPresets?: boolean;\n className?: string;\n}\n\nexport function MonthDayGrid({\n disabled,\n showPresets = true,\n className,\n}: MonthDayGridProps) {\n const { monthDays, toggleMonthDay, setMonthDays } = useCronMonthDays();\n\n // Ensure monthDays is always an array\n const safeMonthDays = Array.isArray(monthDays) ? monthDays : [];\n\n // Prepare presets data\n const is1st = safeMonthDays.length === 1 && safeMonthDays[0] === 1;\n const is15th = safeMonthDays.length === 1 && safeMonthDays[0] === 15;\n const is1stAnd15th = safeMonthDays.length === 2 && safeMonthDays.includes(1) && safeMonthDays.includes(15);\n\n const presets = [\n { label: '1st', isActive: is1st, days: [1] as MonthDay[] },\n { label: '15th', isActive: is15th, days: [15] as MonthDay[] },\n { label: '1st & 15th', isActive: is1stAnd15th, days: [1, 15] as MonthDay[] },\n ];\n\n // Prepare grid cells data\n const gridCells = Array.from({ length: GRID_SIZE }, (_, i) => {\n const day = i + 1;\n const isValidDay = day <= 31;\n const isSelected = isValidDay && safeMonthDays.includes(day as MonthDay);\n const isPartialMonth = day > 28;\n\n if (!isValidDay) {\n return { type: 'empty' as const, key: i };\n }\n\n return {\n type: 'day' as const,\n key: day,\n day: day as MonthDay,\n isSelected,\n className: cn(\n 'aspect-square flex items-center justify-center',\n 'rounded-lg text-sm font-medium',\n 'transition-all duration-150',\n 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50',\n 'active:scale-[0.95]',\n isSelected\n ? 'bg-primary text-primary-foreground shadow-sm'\n : cn(\n 'bg-muted/30 hover:bg-muted/60',\n isPartialMonth\n ? 'text-muted-foreground/50'\n : 'text-muted-foreground'\n ),\n disabled && 'opacity-50 cursor-not-allowed pointer-events-none'\n ),\n };\n });\n\n const selectionCount = safeMonthDays.length;\n\n return (\n <div className={cn('space-y-3', className)}>\n {/* Quick Presets */}\n {showPresets && (\n <div className=\"flex gap-2\">\n {presets.map((preset) => (\n <PresetButton\n key={preset.label}\n label={preset.label}\n isActive={preset.isActive}\n onClick={() => setMonthDays(preset.days)}\n disabled={disabled}\n />\n ))}\n </div>\n )}\n\n {/* Calendar Grid - full width */}\n <div className=\"grid grid-cols-7 gap-1\">\n {gridCells.map((cell) => {\n if (cell.type === 'empty') {\n return <div key={cell.key} className=\"aspect-square\" />;\n }\n\n return (\n <button\n key={cell.key}\n type=\"button\"\n disabled={disabled}\n onClick={() => toggleMonthDay(cell.day)}\n aria-pressed={cell.isSelected}\n aria-label={`Day ${cell.day}`}\n className={cell.className}\n >\n {cell.day}\n </button>\n );\n })}\n </div>\n\n {/* Selection hint */}\n {selectionCount > 1 && (\n <p className=\"text-xs text-muted-foreground text-center\">\n {selectionCount} days selected\n </p>\n )}\n </div>\n );\n}\n\ninterface PresetButtonProps {\n label: string;\n isActive: boolean;\n onClick: () => void;\n disabled?: boolean;\n}\n\nfunction PresetButton({ label, isActive, onClick, disabled }: PresetButtonProps) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onClick}\n className={cn(\n 'flex-1 px-3 py-1.5 rounded-md text-xs font-medium',\n 'transition-colors duration-150',\n 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50',\n isActive\n ? 'bg-primary/15 text-primary border border-primary/30'\n : 'bg-muted/30 text-muted-foreground hover:bg-muted/50 border border-transparent',\n disabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </button>\n );\n}\n","'use client';\n\n/**\n * CustomInput\n *\n * Raw cron expression input with validation and help popover.\n */\n\nimport { useState, useEffect } from 'react';\nimport { Input } from '@djangocfg/ui-core/components';\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { AlertCircle, CheckCircle2 } from 'lucide-react';\nimport { useCronCustom } from '../context/hooks';\nimport { isValidCron } from '../utils/cron-parser';\n\nexport interface CustomInputProps {\n disabled?: boolean;\n className?: string;\n}\n\nexport function CustomInput({ disabled, className }: CustomInputProps) {\n const { customCron, isValid, setCustomCron } = useCronCustom();\n const [localValue, setLocalValue] = useState(customCron);\n const [localValid, setLocalValid] = useState(isValid);\n\n useEffect(() => {\n setLocalValue(customCron);\n setLocalValid(isValid);\n }, [customCron, isValid]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setLocalValue(value);\n const valid = isValidCron(value);\n setLocalValid(valid);\n setCustomCron(value);\n };\n\n return (\n <div className={cn('space-y-2', className)}>\n <span className=\"text-sm text-muted-foreground\">Cron expression</span>\n\n <div className=\"relative\">\n <Input\n type=\"text\"\n value={localValue}\n onChange={handleChange}\n disabled={disabled}\n placeholder=\"* * * * *\"\n className={cn(\n 'font-mono text-base pr-10 h-11',\n !localValid && localValue.trim() && 'border-destructive focus-visible:ring-destructive/50'\n )}\n />\n <div className=\"absolute right-3 top-1/2 -translate-y-1/2\">\n {localValue.trim() && (\n localValid ? (\n <CheckCircle2 className=\"h-5 w-5 text-green-500\" />\n ) : (\n <AlertCircle className=\"h-5 w-5 text-destructive\" />\n )\n )}\n </div>\n </div>\n </div>\n );\n}\n","'use client';\n\n/**\n * CronCheatsheet\n *\n * Popover with cron syntax reference.\n */\n\nimport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n} from '@djangocfg/ui-core/components';\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { HelpCircle } from 'lucide-react';\n\nexport interface CronCheatsheetProps {\n className?: string;\n}\n\nexport function CronCheatsheet({ className }: CronCheatsheetProps) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className={cn(\n 'p-1 rounded hover:bg-muted/50 transition-colors',\n className\n )}\n aria-label=\"Cron syntax help\"\n >\n <HelpCircle className=\"h-4 w-4 text-muted-foreground\" />\n </button>\n </PopoverTrigger>\n <PopoverContent className=\"w-72 p-3\" align=\"end\">\n <div className=\"space-y-3\">\n <p className=\"font-medium text-sm\">Cron Format</p>\n <code className=\"block text-xs bg-muted px-2 py-1.5 rounded font-mono text-center\">\n min hour day month weekday\n </code>\n\n <div className=\"grid grid-cols-2 gap-x-4 gap-y-1 text-xs\">\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">minute</span>\n <span>0-59</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">hour</span>\n <span>0-23</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">day</span>\n <span>1-31</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">month</span>\n <span>1-12</span>\n </div>\n <div className=\"flex justify-between col-span-2\">\n <span className=\"text-muted-foreground\">weekday</span>\n <span>0-6 (Sun-Sat)</span>\n </div>\n </div>\n\n <div className=\"pt-2 border-t border-border space-y-1.5\">\n <p className=\"text-xs font-medium\">Special characters</p>\n <div className=\"grid grid-cols-2 gap-1.5 text-xs\">\n <span><code className=\"bg-muted px-1 rounded\">*</code> any value</span>\n <span><code className=\"bg-muted px-1 rounded\">,</code> list (1,3,5)</span>\n <span><code className=\"bg-muted px-1 rounded\">-</code> range (1-5)</span>\n <span><code className=\"bg-muted px-1 rounded\">/</code> step (*/15)</span>\n </div>\n </div>\n\n <div className=\"pt-2 border-t border-border space-y-1.5\">\n <p className=\"text-xs font-medium\">Examples</p>\n <div className=\"space-y-1 text-xs\">\n <div className=\"flex justify-between font-mono\">\n <span className=\"text-muted-foreground\">0 9 * * *</span>\n <span>daily at 9am</span>\n </div>\n <div className=\"flex justify-between font-mono\">\n <span className=\"text-muted-foreground\">0 9 * * 1-5</span>\n <span>weekdays 9am</span>\n </div>\n <div className=\"flex justify-between font-mono\">\n <span className=\"text-muted-foreground\">*/15 * * * *</span>\n <span>every 15 min</span>\n </div>\n <div className=\"flex justify-between font-mono\">\n <span className=\"text-muted-foreground\">0 0 1 * *</span>\n <span>1st of month</span>\n </div>\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n","'use client';\n\n/**\n * SchedulePreview\n *\n * Human-readable preview with cron expression and cheatsheet.\n */\n\nimport { useState, useCallback } from 'react';\nimport { Calendar, Copy, Check } from 'lucide-react';\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { useCronPreview } from '../context/hooks';\nimport { CronCheatsheet } from './CronCheatsheet';\n\nexport interface SchedulePreviewProps {\n /** Show raw cron expression (default: true) */\n showCronExpression?: boolean;\n /** Enable copy to clipboard */\n allowCopy?: boolean;\n /** Additional CSS classes */\n className?: string;\n}\n\nexport function SchedulePreview({\n showCronExpression = true,\n allowCopy = false,\n className,\n}: SchedulePreviewProps) {\n const { cronExpression, humanDescription, isValid } = useCronPreview();\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(cronExpression);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n }, [cronExpression]);\n\n return (\n <div\n className={cn(\n 'px-3 py-2.5 rounded-lg border',\n 'bg-muted/30 border-border/50',\n !isValid && 'border-destructive/30 bg-destructive/5',\n className\n )}\n >\n {/* Human description */}\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <Calendar\n className={cn(\n 'h-4 w-4 shrink-0',\n isValid ? 'text-primary' : 'text-destructive'\n )}\n />\n <span\n className={cn(\n 'text-sm',\n isValid ? 'text-foreground' : 'text-destructive'\n )}\n >\n {humanDescription}\n </span>\n </div>\n\n {/* Copy Button */}\n {allowCopy && (\n <button\n type=\"button\"\n onClick={handleCopy}\n disabled={!isValid}\n className={cn(\n 'p-1 rounded transition-colors duration-150',\n 'hover:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50',\n 'disabled:opacity-50 disabled:cursor-not-allowed'\n )}\n title={copied ? 'Copied!' : 'Copy cron expression'}\n >\n {copied ? (\n <Check className=\"h-3.5 w-3.5 text-green-500\" />\n ) : (\n <Copy className=\"h-3.5 w-3.5 text-muted-foreground\" />\n )}\n </button>\n )}\n </div>\n\n {/* Cron expression with cheatsheet */}\n {showCronExpression && (\n <div className=\"mt-1.5 pt-1.5 border-t border-border/30 flex items-center justify-between\">\n <code className=\"text-xs font-mono text-muted-foreground\">\n {cronExpression}\n </code>\n <CronCheatsheet />\n </div>\n )}\n </div>\n );\n}\n"]}
|