2025-08-02 11:14:51 +02:00
|
|
|
import {AdvancedCronSelect} from "./advanced-cron-select";
|
|
|
|
|
import {updateDatabaseBackupPolicyAction} from "@/components/wrappers/dashboard/database/cron-button/cron.action";
|
2026-02-10 11:44:45 +01:00
|
|
|
import {useMutation, useQueryClient} from "@tanstack/react-query";
|
2025-08-02 11:14:51 +02:00
|
|
|
import {useState} from "react";
|
|
|
|
|
import {toast} from "sonner";
|
|
|
|
|
import {Button} from "@/components/ui/button";
|
|
|
|
|
import {Separator} from "@/components/ui/separator";
|
2025-08-29 15:31:23 +02:00
|
|
|
import {Database} from "@/db/schema/07_database";
|
2024-12-12 15:32:33 +01:00
|
|
|
|
|
|
|
|
export type CronInputProps = {
|
2025-05-16 15:54:17 +02:00
|
|
|
database: Database;
|
2025-08-02 11:14:51 +02:00
|
|
|
onSuccess?: () => void;
|
2025-05-16 15:54:17 +02:00
|
|
|
};
|
2024-12-12 15:32:33 +01:00
|
|
|
|
2025-08-02 11:14:51 +02:00
|
|
|
export const CronInput = ({database, onSuccess}: CronInputProps) => {
|
2024-12-12 15:32:33 +01:00
|
|
|
const [cron, setCron] = useState<string>(database.backupPolicy ?? "* * * * *");
|
2026-02-10 11:44:45 +01:00
|
|
|
const queryClient = useQueryClient();
|
2024-12-12 15:32:33 +01:00
|
|
|
|
|
|
|
|
const updateBackupPolicy = useMutation({
|
2025-08-02 11:14:51 +02:00
|
|
|
mutationFn: (value: string) => updateDatabaseBackupPolicyAction({databaseId: database.id, backupPolicy: value}),
|
2024-12-12 15:32:33 +01:00
|
|
|
onSuccess: () => {
|
|
|
|
|
toast.success(`Cron updated successfully.`);
|
2025-08-02 11:14:51 +02:00
|
|
|
onSuccess?.()
|
2026-02-10 11:44:45 +01:00
|
|
|
queryClient.invalidateQueries({queryKey: ["database-data", database.id]});
|
2024-12-12 15:32:33 +01:00
|
|
|
},
|
|
|
|
|
onError: () => {
|
|
|
|
|
toast.error(`An error occurred while updating cron value.`);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-16 15:54:17 +02:00
|
|
|
const handleChangeCron = (type: "minute" | "hour" | "day-of-month" | "month" | "day-of-week", value: string) => {
|
2024-12-12 15:32:33 +01:00
|
|
|
const cronParts = cron.split(" ");
|
2025-08-02 11:14:51 +02:00
|
|
|
const indexMap = {minute: 0, hour: 1, "day-of-month": 2, month: 3, "day-of-week": 4};
|
2024-12-12 15:32:33 +01:00
|
|
|
cronParts[indexMap[type]] = value;
|
|
|
|
|
setCron(cronParts.join(" "));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleUpdateCron = async (cron: string) => {
|
|
|
|
|
await updateBackupPolicy.mutateAsync(cron);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<h1>Configure your cron schedule</h1>
|
|
|
|
|
<AdvancedCronSelect
|
|
|
|
|
id="minute"
|
|
|
|
|
label="Minute"
|
2025-08-02 11:14:51 +02:00
|
|
|
options={Array.from({length: 60}, (_, i) => String(i).padStart(2, "0"))}
|
2024-12-12 15:32:33 +01:00
|
|
|
type="minute"
|
|
|
|
|
value={cron.split(" ")[0]}
|
|
|
|
|
defaultValue={cron.split(" ")[0]}
|
|
|
|
|
onValueChange={(value) => handleChangeCron("minute", value)}
|
|
|
|
|
/>
|
|
|
|
|
<AdvancedCronSelect
|
|
|
|
|
id="hour"
|
|
|
|
|
label="Hour"
|
2025-08-02 11:14:51 +02:00
|
|
|
options={Array.from({length: 24}, (_, i) => String(i).padStart(2, "0"))}
|
2024-12-12 15:32:33 +01:00
|
|
|
type="hour"
|
|
|
|
|
value={cron.split(" ")[1]}
|
|
|
|
|
defaultValue={cron.split(" ")[1]}
|
|
|
|
|
onValueChange={(value) => handleChangeCron("hour", value)}
|
|
|
|
|
/>
|
|
|
|
|
<AdvancedCronSelect
|
|
|
|
|
id="day-of-month"
|
|
|
|
|
label="Day of Month"
|
2025-08-02 11:14:51 +02:00
|
|
|
options={Array.from({length: 31}, (_, i) => String(i + 1).padStart(2, "0"))}
|
2024-12-12 15:32:33 +01:00
|
|
|
type="day-of-month"
|
|
|
|
|
value={cron.split(" ")[2]}
|
|
|
|
|
defaultValue={cron.split(" ")[2]}
|
|
|
|
|
onValueChange={(value) => handleChangeCron("day-of-month", value)}
|
|
|
|
|
/>
|
|
|
|
|
<AdvancedCronSelect
|
|
|
|
|
id="month"
|
|
|
|
|
label="Month"
|
|
|
|
|
options={["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]}
|
|
|
|
|
type="month"
|
|
|
|
|
value={cron.split(" ")[3]}
|
|
|
|
|
defaultValue={cron.split(" ")[3]}
|
|
|
|
|
onValueChange={(value) => handleChangeCron("month", value)}
|
|
|
|
|
/>
|
|
|
|
|
<AdvancedCronSelect
|
|
|
|
|
id="day-of-week"
|
|
|
|
|
label="Day of Week"
|
|
|
|
|
options={["0", "1", "2", "3", "4", "5", "6"]}
|
|
|
|
|
type="day-of-week"
|
|
|
|
|
value={cron.split(" ")[4]}
|
|
|
|
|
defaultValue={cron.split(" ")[4]}
|
|
|
|
|
onValueChange={(value) => handleChangeCron("day-of-week", value)}
|
|
|
|
|
/>
|
2025-08-02 11:14:51 +02:00
|
|
|
<Separator/>
|
2024-12-12 15:32:33 +01:00
|
|
|
<div className="grid gap-2">
|
|
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<div className="font-semibold">Cron Expression</div>
|
|
|
|
|
<div className="font-mono text-muted-foreground">{cron}</div>
|
|
|
|
|
</div>
|
2025-08-02 11:14:51 +02:00
|
|
|
<div className="text-sm text-muted-foreground">This cron expression determines when the job will run.
|
|
|
|
|
</div>
|
2024-12-12 15:32:33 +01:00
|
|
|
</div>
|
|
|
|
|
<div className="flex justify-between gap-2">
|
|
|
|
|
<Button
|
|
|
|
|
onClick={async () => {
|
|
|
|
|
setCron("* * * * *");
|
|
|
|
|
await handleUpdateCron("* * * * *");
|
|
|
|
|
}}
|
|
|
|
|
variant="destructive"
|
|
|
|
|
>
|
|
|
|
|
Reset
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={async () => {
|
|
|
|
|
await handleUpdateCron(cron);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Save cron
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
);
|
2025-05-16 15:54:17 +02:00
|
|
|
};
|