Skip to content

Conversation

@nfebe
Copy link
Contributor

@nfebe nfebe commented Jan 5, 2026

No description provided.

nfebe added 2 commits January 5, 2026 22:12
- Add CronJobsView.vue with full CRUD for scheduled tasks
- Support both command and backup task types
- Add search, filter by deployment/type, and pagination
- Show execution history with output/error details
- Add route /cron-jobs and navigation in System group
- Uses existing schedulerApi endpoints (no agent changes)

Signed-off-by: nfebe <fenn25.fn@gmail.com>
Add comprehensive test suite covering view structure, data loading,
filtering, pagination, modal interactions, task actions, execution
history, and form validation.

Signed-off-by: nfebe <fenn25.fn@gmail.com>
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 5, 2026

Deploying flatrun-ui with  Cloudflare Pages  Cloudflare Pages

Latest commit: d73c475
Status: ✅  Deploy successful!
Preview URL: https://932ada10.flatrun-ui.pages.dev
Branch Preview URL: https://feature-cron-jobs-page.flatrun-ui.pages.dev

View logs

@sourceant
Copy link

sourceant bot commented Jan 5, 2026

Code Review Summary

✨ This PR introduces a new CronJobsView component, providing a comprehensive interface for managing scheduled tasks. The implementation includes features like listing, creating, editing, deleting, and running cron jobs, along with viewing execution history. The new view is seamlessly integrated into the dashboard layout and routing. Excellent test coverage has been added for the new component, ensuring its reliability.

🚀 Key Improvements

  • Introduction of a fully-featured CronJobsView for managing scheduled tasks.
  • Comprehensive unit test suite for src/views/CronJobsView.vue, covering various scenarios including data loading, filtering, pagination, modal interactions, and task actions.
  • Clean integration into the existing dashboard navigation and routing structure.

💡 Minor Suggestions

  • Refine the cronToHuman utility function in src/views/CronJobsView.vue to provide more precise human-readable descriptions for common cron patterns, particularly */N intervals.

Copy link

@sourceant sourceant bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete. See the overview comment for a summary.

- Add CronJobForm interface for form object
- Replace magic numbers with named constants for pagination
  and API limits (PAGE_SIZE, RECENT_EXECUTIONS_LIMIT,
  TASK_HISTORY_LIMIT)
Copy link

@sourceant sourceant bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete. See the overview comment for a summary.

Comment on lines +690 to +717
const cronToHuman = (expr: string): string => {
const parts = expr.split(" ");
if (parts.length !== 5) return "Invalid cron expression";

const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;

if (minute === "0" && hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
return "Every hour";
}
if (minute === "*" && hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
return "Every minute";
}
if (dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
if (minute !== "*" && hour !== "*") {
return `Daily at ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`;
}
if (minute !== "*" && hour === "*") {
return `Hourly at minute ${minute}`;
}
}
if (dayOfWeek === "0" && dayOfMonth === "*" && month === "*") {
return `Weekly on Sunday at ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`;
}
if (dayOfMonth === "1" && month === "*" && dayOfWeek === "*") {
return `Monthly on the 1st at ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`;
}

return expr;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cronToHuman function can be enhanced to provide more explicit human-readable descriptions for common cron patterns, especially those involving */N (e.g., "every 5 minutes"). The current implementation might return the raw cron string for such patterns or provide a less precise description like "Hourly at minute */5". Refining the logic to prioritize these common expressions will improve user experience.

Suggested change
const cronToHuman = (expr: string): string => {
const parts = expr.split(" ");
if (parts.length !== 5) return "Invalid cron expression";
const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
if (minute === "0" && hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
return "Every hour";
}
if (minute === "*" && hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
return "Every minute";
}
if (dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
if (minute !== "*" && hour !== "*") {
return `Daily at ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`;
}
if (minute !== "*" && hour === "*") {
return `Hourly at minute ${minute}`;
}
}
if (dayOfWeek === "0" && dayOfMonth === "*" && month === "*") {
return `Weekly on Sunday at ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`;
}
if (dayOfMonth === "1" && month === "*" && dayOfWeek === "*") {
return `Monthly on the 1st at ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`;
}
return expr;
const cronToHuman = (expr: string): string => {
const parts = expr.split(" ");
if (parts.length !== 5) return "Invalid cron expression";
const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
// Every minute
if (minute === "*" && hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
return "Every minute";
}
// Every N minutes
if (minute.startsWith("*/") && hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
const interval = parseInt(minute.substring(2));
if (!isNaN(interval) && interval > 0) return `Every ${interval} minutes`;
}
// Every hour (at minute 0)
if (minute === "0" && hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
return "Every hour";
}
// Every N hours (at minute 0)
if (minute === "0" && hour.startsWith("*/") && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
const interval = parseInt(hour.substring(2));
if (!isNaN(interval) && interval > 0) return `Every ${interval} hours`;
}
// Hourly at specific minute
if (hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
return `Hourly at minute ${minute}`;
}
// Daily at specific time
if (dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
return `Daily at ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`;
}
// Weekly on Sunday at specific time
if (dayOfWeek === "0" && dayOfMonth === "*" && month === "*") {
return `Weekly on Sunday at ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`;
}
// Monthly on the 1st at specific time
if (dayOfMonth === "1" && month === "*" && dayOfWeek === "*") {
return `Monthly on the 1st at ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`;
}
return expr;
};

@nfebe nfebe merged commit 46dd621 into main Jan 5, 2026
5 checks passed
@nfebe nfebe deleted the feature/cron-jobs-page branch January 5, 2026 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants