mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
✨ feat: update the cron patterns fields values (#11399)
feat: update the cron patterns to the right way
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
"agentCronJobs.form.validation.nameRequired": "Task name is required",
|
||||
"agentCronJobs.interval.12hours": "Every 12 hours",
|
||||
"agentCronJobs.interval.1hour": "Every hour",
|
||||
"agentCronJobs.interval.2hours": "Every 2 hours",
|
||||
"agentCronJobs.interval.30min": "Every 30 minutes",
|
||||
"agentCronJobs.interval.6hours": "Every 6 hours",
|
||||
"agentCronJobs.interval.daily": "Daily",
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"agentCronJobs.form.validation.nameRequired": "任务名称不能为空",
|
||||
"agentCronJobs.interval.12hours": "每12小时",
|
||||
"agentCronJobs.interval.1hour": "每小时",
|
||||
"agentCronJobs.interval.2hours": "每2小时",
|
||||
"agentCronJobs.interval.30min": "每30分钟",
|
||||
"agentCronJobs.interval.6hours": "每6小时",
|
||||
"agentCronJobs.interval.daily": "每日",
|
||||
|
||||
@@ -43,7 +43,7 @@ export const agentCronJobs = pgTable(
|
||||
|
||||
// Core configuration
|
||||
enabled: boolean('enabled').default(true),
|
||||
cronPattern: text('cron_pattern').notNull(), // e.g., "0 */30 * * *"
|
||||
cronPattern: text('cron_pattern').notNull(), // e.g., "*/30 * * * *" (every 30 minutes)
|
||||
timezone: text('timezone').default('UTC'),
|
||||
|
||||
// Content fields
|
||||
@@ -82,27 +82,61 @@ export const cronPatternSchema = z
|
||||
'Invalid cron pattern',
|
||||
);
|
||||
|
||||
// Minimum 30 minutes validation
|
||||
// Minimum 30 minutes validation (using standard cron format)
|
||||
export const minimumIntervalSchema = z.string().refine((pattern) => {
|
||||
// For simplicity, we'll validate common patterns
|
||||
// More complex validation can be added later
|
||||
const thirtyMinPatterns = [
|
||||
'0 */30 * * *', // Every 30 minutes
|
||||
'0 0 * * *', // Every hour
|
||||
'0 0 */2 * *', // Every 2 hours
|
||||
'0 0 */6 * *', // Every 6 hours
|
||||
'0 0 0 * *', // Daily
|
||||
'0 0 0 * * 1', // Weekly
|
||||
'0 0 0 1 *', // Monthly
|
||||
// Standard cron format: minute hour day month weekday
|
||||
const allowedPatterns = [
|
||||
'*/30 * * * *', // Every 30 minutes
|
||||
'0 * * * *', // Every hour
|
||||
'0 */2 * * *', // Every 2 hours
|
||||
'0 */3 * * *', // Every 3 hours
|
||||
'0 */4 * * *', // Every 4 hours
|
||||
'0 */6 * * *', // Every 6 hours
|
||||
'0 */8 * * *', // Every 8 hours
|
||||
'0 */12 * * *', // Every 12 hours
|
||||
'0 0 * * *', // Daily at midnight
|
||||
'0 0 * * 0', // Weekly on Sunday
|
||||
'0 0 1 * *', // Monthly on 1st
|
||||
];
|
||||
|
||||
// Check if it matches allowed patterns or follows 30+ minute intervals
|
||||
return (
|
||||
thirtyMinPatterns.includes(pattern) ||
|
||||
pattern.includes('*/30') ||
|
||||
pattern.includes('*/60') ||
|
||||
/0 \d+ \* \* \*/.test(pattern)
|
||||
); // Hours pattern
|
||||
// Check if it matches allowed patterns
|
||||
if (allowedPatterns.includes(pattern)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parse pattern to validate minimum 30-minute interval
|
||||
const parts = pattern.split(' ');
|
||||
if (parts.length !== 5) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const [minute, hour] = parts;
|
||||
|
||||
// Allow minute intervals >= 30 (e.g., */30, */45, */60)
|
||||
if (minute.startsWith('*/')) {
|
||||
const interval = parseInt(minute.slice(2));
|
||||
if (!isNaN(interval) && interval >= 30) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow hourly patterns: 0 */N * * * where N >= 1
|
||||
if (minute === '0' && hour.startsWith('*/')) {
|
||||
const interval = parseInt(hour.slice(2));
|
||||
if (!isNaN(interval) && interval >= 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow specific hour patterns: 0 N * * * (runs once per day)
|
||||
if (minute === '0' && /^\d+$/.test(hour)) {
|
||||
const h = parseInt(hour);
|
||||
if (!isNaN(h) && h >= 0 && h <= 23) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}, 'Minimum execution interval is 30 minutes');
|
||||
|
||||
export const executionConditionsSchema = z
|
||||
|
||||
@@ -85,13 +85,15 @@ const AutoSaveHintSlot = memo(() => {
|
||||
return <AutoSaveHint lastUpdatedTime={lastUpdatedTime} saveStatus={status} />;
|
||||
});
|
||||
|
||||
// Standard cron format: minute hour day month weekday
|
||||
const CRON_PATTERNS = [
|
||||
{ label: 'agentCronJobs.interval.30min', value: '0 */30 * * *' },
|
||||
{ label: 'agentCronJobs.interval.1hour', value: '0 0 * * *' },
|
||||
{ label: 'agentCronJobs.interval.30min', value: '*/30 * * * *' },
|
||||
{ label: 'agentCronJobs.interval.1hour', value: '0 * * * *' },
|
||||
{ label: 'agentCronJobs.interval.2hours', value: '0 */2 * * *' },
|
||||
{ label: 'agentCronJobs.interval.6hours', value: '0 */6 * * *' },
|
||||
{ label: 'agentCronJobs.interval.12hours', value: '0 */12 * * *' },
|
||||
{ label: 'agentCronJobs.interval.daily', value: '0 0 0 * *' },
|
||||
{ label: 'agentCronJobs.interval.weekly', value: '0 0 0 * 0' },
|
||||
{ label: 'agentCronJobs.interval.daily', value: '0 0 * * *' },
|
||||
{ label: 'agentCronJobs.interval.weekly', value: '0 0 * * 0' },
|
||||
];
|
||||
|
||||
const WEEKDAY_OPTIONS = [
|
||||
@@ -115,13 +117,15 @@ const WEEKDAY_LABELS: Record<number, string> = {
|
||||
};
|
||||
|
||||
const getIntervalText = (cronPattern: string) => {
|
||||
// Standard cron format mapping
|
||||
const intervalMap: Record<string, string> = {
|
||||
'*/30 * * * *': 'agentCronJobs.interval.30min',
|
||||
'0 * * * *': 'agentCronJobs.interval.1hour',
|
||||
'0 */12 * * *': 'agentCronJobs.interval.12hours',
|
||||
'0 */30 * * *': 'agentCronJobs.interval.30min',
|
||||
'0 */2 * * *': 'agentCronJobs.interval.2hours',
|
||||
'0 */6 * * *': 'agentCronJobs.interval.6hours',
|
||||
'0 0 * * *': 'agentCronJobs.interval.1hour',
|
||||
'0 0 0 * *': 'agentCronJobs.interval.daily',
|
||||
'0 0 0 * 0': 'agentCronJobs.interval.weekly',
|
||||
'0 0 * * *': 'agentCronJobs.interval.daily',
|
||||
'0 0 * * 0': 'agentCronJobs.interval.weekly',
|
||||
};
|
||||
|
||||
return intervalMap[cronPattern] || cronPattern;
|
||||
|
||||
@@ -26,13 +26,15 @@ interface CronJobFormProps {
|
||||
onSubmit: (data: CronJobFormData) => void;
|
||||
}
|
||||
|
||||
// Standard cron format: minute hour day month weekday
|
||||
const CRON_PATTERNS = [
|
||||
{ label: 'agentCronJobs.interval.30min', value: '0 */30 * * *' },
|
||||
{ label: 'agentCronJobs.interval.1hour', value: '0 0 * * *' },
|
||||
{ label: 'agentCronJobs.interval.6hours', value: '0 */6 * * *' },
|
||||
{ label: 'agentCronJobs.interval.12hours', value: '0 */12 * * *' },
|
||||
{ label: 'agentCronJobs.interval.daily', value: '0 0 0 * *' },
|
||||
{ label: 'agentCronJobs.interval.weekly', value: '0 0 0 * 0' },
|
||||
{ label: 'agentCronJobs.interval.30min', value: '*/30 * * * *' }, // Every 30 minutes
|
||||
{ label: 'agentCronJobs.interval.1hour', value: '0 * * * *' }, // Every hour
|
||||
{ label: 'agentCronJobs.interval.2hours', value: '0 */2 * * *' }, // Every 2 hours
|
||||
{ label: 'agentCronJobs.interval.6hours', value: '0 */6 * * *' }, // Every 6 hours
|
||||
{ label: 'agentCronJobs.interval.12hours', value: '0 */12 * * *' }, // Every 12 hours
|
||||
{ label: 'agentCronJobs.interval.daily', value: '0 0 * * *' }, // Daily at midnight
|
||||
{ label: 'agentCronJobs.interval.weekly', value: '0 0 * * 0' }, // Weekly on Sunday
|
||||
];
|
||||
|
||||
const WEEKDAY_OPTIONS = [
|
||||
@@ -120,7 +122,7 @@ const CronJobForm = memo<CronJobFormProps>(({ editingJob, formRef, onSubmit }) =
|
||||
<Form
|
||||
form={form}
|
||||
initialValues={{
|
||||
cronPattern: '0 */30 * * *', // Default to 30 minutes
|
||||
cronPattern: '*/30 * * * *', // Default to every 30 minutes
|
||||
weekdays: [],
|
||||
}}
|
||||
layout="vertical"
|
||||
|
||||
Reference in New Issue
Block a user