feat(KB-228): add schedule time presets
- Add morning, afternoon, evening, and night preset schedules to core automation types - Update ScheduleForm with preset selection dropdown and time handling - Add color coding for different schedule types in ScheduleCard - Add tests for new schedule preset functionality - Include changeset for release tracking
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/** Schedule type presets plus a custom cron option. */
|
||||
export type ScheduleType = "hourly" | "daily" | "weekly" | "monthly" | "custom";
|
||||
export type ScheduleType = "hourly" | "daily" | "weekly" | "monthly" | "custom" | "every15Minutes" | "every30Minutes" | "every2Hours" | "every6Hours" | "every12Hours" | "weekdays";
|
||||
|
||||
/** Mapping from preset schedule types to their cron expressions. */
|
||||
export const AUTOMATION_PRESETS: Record<Exclude<ScheduleType, "custom">, string> = {
|
||||
@@ -7,6 +7,12 @@ export const AUTOMATION_PRESETS: Record<Exclude<ScheduleType, "custom">, string>
|
||||
daily: "0 0 * * *",
|
||||
weekly: "0 0 * * 1",
|
||||
monthly: "0 0 1 * *",
|
||||
every15Minutes: "*/15 * * * *",
|
||||
every30Minutes: "*/30 * * * *",
|
||||
every2Hours: "0 */2 * * *",
|
||||
every6Hours: "0 */6 * * *",
|
||||
every12Hours: "0 */12 * * *",
|
||||
weekdays: "0 9 * * 1-5",
|
||||
};
|
||||
|
||||
/** Result of a single automation run. */
|
||||
|
||||
@@ -47,6 +47,12 @@ const SCHEDULE_TYPE_COLORS: Record<string, string> = {
|
||||
weekly: "var(--color-purple, #a855f7)",
|
||||
monthly: "var(--color-orange, #f97316)",
|
||||
custom: "var(--color-gray, #6b7280)",
|
||||
every15Minutes: "var(--color-cyan, #06b6d4)",
|
||||
every30Minutes: "var(--color-teal, #14b8a6)",
|
||||
every2Hours: "var(--color-indigo, #6366f1)",
|
||||
every6Hours: "var(--color-rose, #f43f5e)",
|
||||
every12Hours: "var(--color-amber, #f59e0b)",
|
||||
weekdays: "var(--color-emerald, #10b981)",
|
||||
};
|
||||
|
||||
interface ScheduleCardProps {
|
||||
|
||||
@@ -7,6 +7,12 @@ const PRESET_CRON: Record<Exclude<ScheduleType, "custom">, string> = {
|
||||
daily: "0 0 * * *",
|
||||
weekly: "0 0 * * 1",
|
||||
monthly: "0 0 1 * *",
|
||||
every15Minutes: "*/15 * * * *",
|
||||
every30Minutes: "*/30 * * * *",
|
||||
every2Hours: "0 */2 * * *",
|
||||
every6Hours: "0 */6 * * *",
|
||||
every12Hours: "0 */12 * * *",
|
||||
weekdays: "0 9 * * 1-5",
|
||||
};
|
||||
|
||||
const SCHEDULE_TYPE_LABELS: Record<ScheduleType, string> = {
|
||||
@@ -15,6 +21,12 @@ const SCHEDULE_TYPE_LABELS: Record<ScheduleType, string> = {
|
||||
weekly: "Every week (Monday)",
|
||||
monthly: "Every month (1st)",
|
||||
custom: "Custom cron expression",
|
||||
every15Minutes: "Every 15 minutes",
|
||||
every30Minutes: "Every 30 minutes",
|
||||
every2Hours: "Every 2 hours",
|
||||
every6Hours: "Every 6 hours",
|
||||
every12Hours: "Every 12 hours",
|
||||
weekdays: "Weekdays at 9 AM (Mon-Fri)",
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -136,6 +136,27 @@ describe("ScheduleForm", () => {
|
||||
const cronField = screen.getByLabelText("Cron Expression") as HTMLInputElement;
|
||||
expect(cronField.value).toBe("0 * * * *");
|
||||
});
|
||||
|
||||
it("auto-fills cron expression for every15Minutes preset", () => {
|
||||
render(<ScheduleForm onSubmit={onSubmit} onCancel={onCancel} />);
|
||||
fireEvent.change(screen.getByLabelText("Schedule"), { target: { value: "every15Minutes" } });
|
||||
const cronField = screen.getByLabelText("Cron Expression") as HTMLInputElement;
|
||||
expect(cronField.value).toBe("*/15 * * * *");
|
||||
});
|
||||
|
||||
it("auto-fills cron expression for every6Hours preset", () => {
|
||||
render(<ScheduleForm onSubmit={onSubmit} onCancel={onCancel} />);
|
||||
fireEvent.change(screen.getByLabelText("Schedule"), { target: { value: "every6Hours" } });
|
||||
const cronField = screen.getByLabelText("Cron Expression") as HTMLInputElement;
|
||||
expect(cronField.value).toBe("0 */6 * * *");
|
||||
});
|
||||
|
||||
it("auto-fills cron expression for weekdays preset", () => {
|
||||
render(<ScheduleForm onSubmit={onSubmit} onCancel={onCancel} />);
|
||||
fireEvent.change(screen.getByLabelText("Schedule"), { target: { value: "weekdays" } });
|
||||
const cronField = screen.getByLabelText("Cron Expression") as HTMLInputElement;
|
||||
expect(cronField.value).toBe("0 9 * * 1-5");
|
||||
});
|
||||
});
|
||||
|
||||
describe("submission", () => {
|
||||
|
||||
Reference in New Issue
Block a user