mirror of
https://github.com/fccview/cronmaster.git
synced 2025-12-23 22:18:20 -05:00
send fixes to develop for automatic ID assignation
This commit is contained in:
@@ -215,7 +215,7 @@ export const CronJobList = ({ cronJobs, scripts }: CronJobListProps) => {
|
||||
onNewTaskClick={() => setIsNewCronModalOpen(true)}
|
||||
/>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-3 max-h-[60vh] overflow-y-auto">
|
||||
{filteredJobs.map((job) => (
|
||||
<CronJobItem
|
||||
key={job.id}
|
||||
|
||||
@@ -69,7 +69,7 @@ export const refreshJobErrors = (
|
||||
setJobErrors(errors);
|
||||
};
|
||||
|
||||
export const handleDelete = async (id: string, props: HandlerProps) => {
|
||||
export const handleDelete = async (job: CronJob, props: HandlerProps) => {
|
||||
const {
|
||||
setDeletingId,
|
||||
setIsDeleteModalOpen,
|
||||
@@ -77,19 +77,25 @@ export const handleDelete = async (id: string, props: HandlerProps) => {
|
||||
refreshJobErrors,
|
||||
} = props;
|
||||
|
||||
setDeletingId(id);
|
||||
setDeletingId(job.id);
|
||||
try {
|
||||
const result = await removeCronJob(id);
|
||||
const result = await removeCronJob({
|
||||
id: job.id,
|
||||
schedule: job.schedule,
|
||||
command: job.command,
|
||||
comment: job.comment,
|
||||
user: job.user,
|
||||
});
|
||||
if (result.success) {
|
||||
showToast("success", "Cron job deleted successfully");
|
||||
} else {
|
||||
const errorId = `delete-${id}-${Date.now()}`;
|
||||
const errorId = `delete-${job.id}-${Date.now()}`;
|
||||
const jobError: JobError = {
|
||||
id: errorId,
|
||||
title: "Failed to delete cron job",
|
||||
message: result.message,
|
||||
timestamp: new Date().toISOString(),
|
||||
jobId: id,
|
||||
jobId: job.id,
|
||||
};
|
||||
setJobError(jobError);
|
||||
refreshJobErrors();
|
||||
@@ -107,14 +113,14 @@ export const handleDelete = async (id: string, props: HandlerProps) => {
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
const errorId = `delete-${id}-${Date.now()}`;
|
||||
const errorId = `delete-${job.id}-${Date.now()}`;
|
||||
const jobError: JobError = {
|
||||
id: errorId,
|
||||
title: "Failed to delete cron job",
|
||||
message: error.message || "Please try again later.",
|
||||
details: error.stack,
|
||||
timestamp: new Date().toISOString(),
|
||||
jobId: id,
|
||||
jobId: job.id,
|
||||
};
|
||||
setJobError(jobError);
|
||||
showToast(
|
||||
@@ -158,9 +164,15 @@ export const handleClone = async (newComment: string, props: HandlerProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const handlePause = async (id: string) => {
|
||||
export const handlePause = async (job: any) => {
|
||||
try {
|
||||
const result = await pauseCronJobAction(id);
|
||||
const result = await pauseCronJobAction({
|
||||
id: job.id,
|
||||
schedule: job.schedule,
|
||||
command: job.command,
|
||||
comment: job.comment,
|
||||
user: job.user,
|
||||
});
|
||||
if (result.success) {
|
||||
showToast("success", "Cron job paused successfully");
|
||||
} else {
|
||||
@@ -171,9 +183,16 @@ export const handlePause = async (id: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const handleToggleLogging = async (id: string) => {
|
||||
export const handleToggleLogging = async (job: any) => {
|
||||
try {
|
||||
const result = await toggleCronJobLogging(id);
|
||||
const result = await toggleCronJobLogging({
|
||||
id: job.id,
|
||||
schedule: job.schedule,
|
||||
command: job.command,
|
||||
comment: job.comment,
|
||||
user: job.user,
|
||||
logsEnabled: job.logsEnabled,
|
||||
});
|
||||
if (result.success) {
|
||||
showToast("success", result.message);
|
||||
} else {
|
||||
@@ -185,9 +204,15 @@ export const handleToggleLogging = async (id: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const handleResume = async (id: string) => {
|
||||
export const handleResume = async (job: any) => {
|
||||
try {
|
||||
const result = await resumeCronJobAction(id);
|
||||
const result = await resumeCronJobAction({
|
||||
id: job.id,
|
||||
schedule: job.schedule,
|
||||
command: job.command,
|
||||
comment: job.comment,
|
||||
user: job.user,
|
||||
});
|
||||
if (result.success) {
|
||||
showToast("success", "Cron job resumed successfully");
|
||||
} else {
|
||||
@@ -401,9 +426,9 @@ export const handleNewCronSubmit = async (
|
||||
}
|
||||
};
|
||||
|
||||
export const handleBackup = async (id: string) => {
|
||||
export const handleBackup = async (job: any) => {
|
||||
try {
|
||||
const result = await backupCronJob(id);
|
||||
const result = await backupCronJob(job);
|
||||
if (result.success) {
|
||||
showToast("success", "Job backed up successfully");
|
||||
} else {
|
||||
|
||||
@@ -127,7 +127,10 @@ export const useCronJobState = ({ cronJobs, scripts }: CronJobListProps) => {
|
||||
};
|
||||
|
||||
const handleDeleteLocal = async (id: string) => {
|
||||
await handleDelete(id, getHelperState());
|
||||
const job = cronJobs.find(j => j.id === id);
|
||||
if (job) {
|
||||
await handleDelete(job, getHelperState());
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloneLocal = async (newComment: string) => {
|
||||
@@ -135,11 +138,17 @@ export const useCronJobState = ({ cronJobs, scripts }: CronJobListProps) => {
|
||||
};
|
||||
|
||||
const handlePauseLocal = async (id: string) => {
|
||||
await handlePause(id);
|
||||
const job = cronJobs.find(j => j.id === id);
|
||||
if (job) {
|
||||
await handlePause(job);
|
||||
}
|
||||
};
|
||||
|
||||
const handleResumeLocal = async (id: string) => {
|
||||
await handleResume(id);
|
||||
const job = cronJobs.find(j => j.id === id);
|
||||
if (job) {
|
||||
await handleResume(job);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRunLocal = async (id: string) => {
|
||||
@@ -149,7 +158,10 @@ export const useCronJobState = ({ cronJobs, scripts }: CronJobListProps) => {
|
||||
};
|
||||
|
||||
const handleToggleLoggingLocal = async (id: string) => {
|
||||
await handleToggleLogging(id);
|
||||
const job = cronJobs.find(j => j.id === id);
|
||||
if (job) {
|
||||
await handleToggleLogging(job);
|
||||
}
|
||||
};
|
||||
|
||||
const handleViewLogs = (job: CronJob) => {
|
||||
@@ -187,7 +199,10 @@ export const useCronJobState = ({ cronJobs, scripts }: CronJobListProps) => {
|
||||
};
|
||||
|
||||
const handleBackupLocal = async (id: string) => {
|
||||
await handleBackup(id);
|
||||
const job = cronJobs.find(j => j.id === id);
|
||||
if (job) {
|
||||
await handleBackup(job);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -3,25 +3,27 @@
|
||||
import {
|
||||
getCronJobs,
|
||||
addCronJob,
|
||||
deleteCronJob,
|
||||
updateCronJob,
|
||||
pauseCronJob,
|
||||
resumeCronJob,
|
||||
cleanupCrontab,
|
||||
readUserCrontab,
|
||||
writeUserCrontab,
|
||||
findJobIndex,
|
||||
updateCronJob,
|
||||
type CronJob,
|
||||
} from "@/app/_utils/cronjob-utils";
|
||||
import { getAllTargetUsers, getUserInfo } from "@/app/_utils/crontab-utils";
|
||||
import { getAllTargetUsers } from "@/app/_utils/crontab-utils";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { getScriptPathForCron } from "@/app/_server/actions/scripts";
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import { isDocker } from "@/app/_server/actions/global";
|
||||
import {
|
||||
runJobSynchronously,
|
||||
runJobInBackground,
|
||||
} from "@/app/_utils/job-execution-utils";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
import {
|
||||
pauseJobInLines,
|
||||
resumeJobInLines,
|
||||
deleteJobInLines,
|
||||
} from "@/app/_utils/line-manipulation-utils";
|
||||
import { cleanCrontabContent } from "@/app/_utils/files-manipulation-utils";
|
||||
|
||||
export const fetchCronJobs = async (): Promise<CronJob[]> => {
|
||||
try {
|
||||
@@ -90,10 +92,22 @@ export const createCronJob = async (
|
||||
};
|
||||
|
||||
export const removeCronJob = async (
|
||||
id: string
|
||||
jobData: { id: string; schedule: string; command: string; comment?: string; user: string }
|
||||
): Promise<{ success: boolean; message: string; details?: string }> => {
|
||||
try {
|
||||
const success = await deleteCronJob(id);
|
||||
const cronContent = await readUserCrontab(jobData.user);
|
||||
const lines = cronContent.split("\n");
|
||||
|
||||
const jobIndex = findJobIndex(jobData, lines, jobData.user);
|
||||
|
||||
if (jobIndex === -1) {
|
||||
return { success: false, message: "Cron job not found in crontab" };
|
||||
}
|
||||
|
||||
const newCronEntries = deleteJobInLines(lines, jobIndex);
|
||||
const newCron = await cleanCrontabContent(newCronEntries.join("\n"));
|
||||
const success = await writeUserCrontab(jobData.user, newCron);
|
||||
|
||||
if (success) {
|
||||
revalidatePath("/");
|
||||
return { success: true, message: "Cron job deleted successfully" };
|
||||
@@ -124,8 +138,15 @@ export const editCronJob = async (
|
||||
return { success: false, message: "Missing required fields" };
|
||||
}
|
||||
|
||||
const cronJobs = await getCronJobs(false);
|
||||
const job = cronJobs.find((j) => j.id === id);
|
||||
|
||||
if (!job) {
|
||||
return { success: false, message: "Cron job not found" };
|
||||
}
|
||||
|
||||
const success = await updateCronJob(
|
||||
id,
|
||||
job,
|
||||
schedule,
|
||||
command,
|
||||
comment,
|
||||
@@ -152,7 +173,7 @@ export const cloneCronJob = async (
|
||||
newComment: string
|
||||
): Promise<{ success: boolean; message: string; details?: string }> => {
|
||||
try {
|
||||
const cronJobs = await getCronJobs();
|
||||
const cronJobs = await getCronJobs(false);
|
||||
const originalJob = cronJobs.find((job) => job.id === id);
|
||||
|
||||
if (!originalJob) {
|
||||
@@ -183,10 +204,22 @@ export const cloneCronJob = async (
|
||||
};
|
||||
|
||||
export const pauseCronJobAction = async (
|
||||
id: string
|
||||
jobData: { id: string; schedule: string; command: string; comment?: string; user: string }
|
||||
): Promise<{ success: boolean; message: string; details?: string }> => {
|
||||
try {
|
||||
const success = await pauseCronJob(id);
|
||||
const cronContent = await readUserCrontab(jobData.user);
|
||||
const lines = cronContent.split("\n");
|
||||
|
||||
const jobIndex = findJobIndex(jobData, lines, jobData.user);
|
||||
|
||||
if (jobIndex === -1) {
|
||||
return { success: false, message: "Cron job not found in crontab" };
|
||||
}
|
||||
|
||||
const newCronEntries = pauseJobInLines(lines, jobIndex, jobData.id);
|
||||
const newCron = await cleanCrontabContent(newCronEntries.join("\n"));
|
||||
const success = await writeUserCrontab(jobData.user, newCron);
|
||||
|
||||
if (success) {
|
||||
revalidatePath("/");
|
||||
return { success: true, message: "Cron job paused successfully" };
|
||||
@@ -204,10 +237,22 @@ export const pauseCronJobAction = async (
|
||||
};
|
||||
|
||||
export const resumeCronJobAction = async (
|
||||
id: string
|
||||
jobData: { id: string; schedule: string; command: string; comment?: string; user: string }
|
||||
): Promise<{ success: boolean; message: string; details?: string }> => {
|
||||
try {
|
||||
const success = await resumeCronJob(id);
|
||||
const cronContent = await readUserCrontab(jobData.user);
|
||||
const lines = cronContent.split("\n");
|
||||
|
||||
const jobIndex = findJobIndex(jobData, lines, jobData.user);
|
||||
|
||||
if (jobIndex === -1) {
|
||||
return { success: false, message: "Cron job not found in crontab" };
|
||||
}
|
||||
|
||||
const newCronEntries = resumeJobInLines(lines, jobIndex, jobData.id);
|
||||
const newCron = await cleanCrontabContent(newCronEntries.join("\n"));
|
||||
const success = await writeUserCrontab(jobData.user, newCron);
|
||||
|
||||
if (success) {
|
||||
revalidatePath("/");
|
||||
return { success: true, message: "Cron job resumed successfully" };
|
||||
@@ -257,23 +302,16 @@ export const cleanupCrontabAction = async (): Promise<{
|
||||
};
|
||||
|
||||
export const toggleCronJobLogging = async (
|
||||
id: string
|
||||
jobData: { id: string; schedule: string; command: string; comment?: string; user: string; logsEnabled?: boolean }
|
||||
): Promise<{ success: boolean; message: string; details?: string }> => {
|
||||
try {
|
||||
const cronJobs = await getCronJobs();
|
||||
const job = cronJobs.find((j) => j.id === id);
|
||||
|
||||
if (!job) {
|
||||
return { success: false, message: "Cron job not found" };
|
||||
}
|
||||
|
||||
const newLogsEnabled = !job.logsEnabled;
|
||||
const newLogsEnabled = !jobData.logsEnabled;
|
||||
|
||||
const success = await updateCronJob(
|
||||
id,
|
||||
job.schedule,
|
||||
job.command,
|
||||
job.comment || "",
|
||||
jobData,
|
||||
jobData.schedule,
|
||||
jobData.command,
|
||||
jobData.comment || "",
|
||||
newLogsEnabled
|
||||
);
|
||||
|
||||
@@ -309,7 +347,7 @@ export const runCronJob = async (
|
||||
mode?: "sync" | "async";
|
||||
}> => {
|
||||
try {
|
||||
const cronJobs = await getCronJobs();
|
||||
const cronJobs = await getCronJobs(false);
|
||||
const job = cronJobs.find((j) => j.id === id);
|
||||
|
||||
if (!job) {
|
||||
@@ -356,7 +394,7 @@ export const executeJob = async (
|
||||
mode?: "sync" | "async";
|
||||
}> => {
|
||||
try {
|
||||
const cronJobs = await getCronJobs();
|
||||
const cronJobs = await getCronJobs(false);
|
||||
const job = cronJobs.find((j) => j.id === id);
|
||||
|
||||
if (!job) {
|
||||
@@ -388,13 +426,13 @@ export const executeJob = async (
|
||||
};
|
||||
|
||||
export const backupCronJob = async (
|
||||
id: string
|
||||
job: CronJob
|
||||
): Promise<{ success: boolean; message: string; details?: string }> => {
|
||||
try {
|
||||
const {
|
||||
backupJobToFile,
|
||||
} = await import("@/app/_utils/backup-utils");
|
||||
const success = await backupJobToFile(id);
|
||||
const success = await backupJobToFile(job);
|
||||
if (success) {
|
||||
return { success: true, message: "Cron job backed up successfully" };
|
||||
} else {
|
||||
|
||||
@@ -17,18 +17,10 @@ const sanitizeFilename = (id: string): string => {
|
||||
return id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
||||
};
|
||||
|
||||
export const backupJobToFile = async (id: string): Promise<boolean> => {
|
||||
export const backupJobToFile = async (job: CronJob): Promise<boolean> => {
|
||||
try {
|
||||
await ensureBackupDirectoryExists();
|
||||
|
||||
const cronJobs = await getCronJobs(false);
|
||||
const job = cronJobs.find((j) => j.id === id);
|
||||
|
||||
if (!job) {
|
||||
console.error(`Job with id ${id} not found`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const jobData = {
|
||||
id: job.id,
|
||||
schedule: job.schedule,
|
||||
@@ -40,14 +32,14 @@ export const backupJobToFile = async (id: string): Promise<boolean> => {
|
||||
backedUpAt: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const filename = `${sanitizeFilename(id)}.job`;
|
||||
const filename = `${sanitizeFilename(job.id)}.job`;
|
||||
const filepath = path.join(BACKUP_DIR, filename);
|
||||
|
||||
await fs.writeFile(filepath, JSON.stringify(jobData, null, 2), "utf8");
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`Error backing up job ${id}:`, error);
|
||||
console.error(`Error backing up job ${job.id}:`, error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -64,7 +56,7 @@ export const backupAllJobsToFiles = async (): Promise<{
|
||||
let successCount = 0;
|
||||
|
||||
for (const job of cronJobs) {
|
||||
const success = await backupJobToFile(job.id);
|
||||
const success = await backupJobToFile(job);
|
||||
if (success) {
|
||||
successCount++;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export interface CronJob {
|
||||
};
|
||||
}
|
||||
|
||||
const readUserCrontab = async (user: string): Promise<string> => {
|
||||
export const readUserCrontab = async (user: string): Promise<string> => {
|
||||
const docker = await isDocker();
|
||||
|
||||
if (docker) {
|
||||
@@ -59,7 +59,7 @@ const readUserCrontab = async (user: string): Promise<string> => {
|
||||
}
|
||||
};
|
||||
|
||||
const writeUserCrontab = async (
|
||||
export const writeUserCrontab = async (
|
||||
user: string,
|
||||
content: string
|
||||
): Promise<boolean> => {
|
||||
@@ -115,33 +115,6 @@ export const getCronJobs = async (
|
||||
const lines = content.split("\n");
|
||||
const jobs = parseJobsFromLines(lines, user);
|
||||
|
||||
let needsUpdate = false;
|
||||
let updatedLines = [...lines];
|
||||
|
||||
for (let jobIndex = 0; jobIndex < jobs.length; jobIndex++) {
|
||||
const job = jobs[jobIndex];
|
||||
|
||||
const cronContent = lines.join("\n");
|
||||
if (!cronContent.includes(`id: ${job.id}`)) {
|
||||
needsUpdate = true;
|
||||
|
||||
updatedLines = updateJobInLines(
|
||||
updatedLines,
|
||||
jobIndex,
|
||||
job.schedule,
|
||||
job.command,
|
||||
job.comment || "",
|
||||
job.logsEnabled || false,
|
||||
job.id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (needsUpdate) {
|
||||
const newCron = await cleanCrontabContent(updatedLines.join("\n"));
|
||||
await writeUserCrontab(user, newCron);
|
||||
}
|
||||
|
||||
allJobs.push(...jobs);
|
||||
}
|
||||
|
||||
@@ -278,46 +251,38 @@ export const deleteCronJob = async (id: string): Promise<boolean> => {
|
||||
};
|
||||
|
||||
export const updateCronJob = async (
|
||||
id: string,
|
||||
jobData: { id: string; schedule: string; command: string; comment?: string; user: string },
|
||||
schedule: string,
|
||||
command: string,
|
||||
comment: string = "",
|
||||
logsEnabled: boolean = false
|
||||
): Promise<boolean> => {
|
||||
try {
|
||||
const allJobs = await getCronJobs(false);
|
||||
const targetJob = allJobs.find((j) => j.id === id);
|
||||
|
||||
if (!targetJob) {
|
||||
console.error(`Job with id ${id} not found`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const user = targetJob.user;
|
||||
const user = jobData.user;
|
||||
const cronContent = await readUserCrontab(user);
|
||||
const lines = cronContent.split("\n");
|
||||
const userJobs = parseJobsFromLines(lines, user);
|
||||
const jobIndex = userJobs.findIndex((j) => j.id === id);
|
||||
|
||||
const jobIndex = findJobIndex(jobData, lines, user);
|
||||
|
||||
if (jobIndex === -1) {
|
||||
console.error(`Job with id ${id} not found in parsed jobs`);
|
||||
console.error(`Job not found in crontab`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const isWrappd = isCommandWrapped(command);
|
||||
const isWrapped = isCommandWrapped(command);
|
||||
|
||||
let finalCommand = command;
|
||||
|
||||
if (logsEnabled && !isWrappd) {
|
||||
if (logsEnabled && !isWrapped) {
|
||||
const docker = await isDocker();
|
||||
finalCommand = await wrapCommandWithLogger(id, command, docker, comment);
|
||||
} else if (!logsEnabled && isWrappd) {
|
||||
finalCommand = await wrapCommandWithLogger(jobData.id, command, docker, comment);
|
||||
} else if (!logsEnabled && isWrapped) {
|
||||
finalCommand = unwrapCommand(command);
|
||||
} else if (logsEnabled && isWrappd) {
|
||||
} else if (logsEnabled && isWrapped) {
|
||||
const unwrapped = unwrapCommand(command);
|
||||
const docker = await isDocker();
|
||||
finalCommand = await wrapCommandWithLogger(
|
||||
id,
|
||||
jobData.id,
|
||||
unwrapped,
|
||||
docker,
|
||||
comment
|
||||
@@ -333,7 +298,7 @@ export const updateCronJob = async (
|
||||
finalCommand,
|
||||
comment,
|
||||
logsEnabled,
|
||||
id
|
||||
jobData.id
|
||||
);
|
||||
const newCron = await cleanCrontabContent(newCronEntries.join("\n"));
|
||||
|
||||
@@ -423,3 +388,24 @@ export const cleanupCrontab = async (): Promise<boolean> => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const findJobIndex = (
|
||||
jobData: { id: string; schedule: string; command: string; comment?: string; user: string; paused?: boolean },
|
||||
lines: string[],
|
||||
user: string
|
||||
): number => {
|
||||
const cronContentStr = lines.join("\n");
|
||||
const userJobs = parseJobsFromLines(lines, user);
|
||||
|
||||
if (cronContentStr.includes(`id: ${jobData.id}`)) {
|
||||
return userJobs.findIndex((j) => j.id === jobData.id);
|
||||
}
|
||||
|
||||
return userJobs.findIndex(
|
||||
(j) =>
|
||||
j.schedule === jobData.schedule &&
|
||||
j.command === jobData.command &&
|
||||
j.user === jobData.user &&
|
||||
(j.comment || "") === (jobData.comment || "")
|
||||
);
|
||||
};
|
||||
|
||||
@@ -175,17 +175,34 @@ export const parseCommentMetadata = (
|
||||
let uuid: string | undefined;
|
||||
|
||||
if (parts.length > 1) {
|
||||
comment = parts[0] || "";
|
||||
const metadata = parts.slice(1).join("|").trim();
|
||||
const firstPartIsMetadata = parts[0].match(/logsEnabled:\s*(true|false)/i) || parts[0].match(/id:\s*([a-z0-9]{4}-[a-z0-9]{4})/i);
|
||||
|
||||
const logsMatch = metadata.match(/logsEnabled:\s*(true|false)/i);
|
||||
if (logsMatch) {
|
||||
logsEnabled = logsMatch[1].toLowerCase() === "true";
|
||||
}
|
||||
if (firstPartIsMetadata) {
|
||||
comment = "";
|
||||
const metadata = parts.join("|").trim();
|
||||
|
||||
const uuidMatch = metadata.match(/id:\s*([a-z0-9]{4}-[a-z0-9]{4})/i);
|
||||
if (uuidMatch) {
|
||||
uuid = uuidMatch[1].toLowerCase();
|
||||
const logsMatch = metadata.match(/logsEnabled:\s*(true|false)/i);
|
||||
if (logsMatch) {
|
||||
logsEnabled = logsMatch[1].toLowerCase() === "true";
|
||||
}
|
||||
|
||||
const uuidMatch = metadata.match(/id:\s*([a-z0-9]{4}-[a-z0-9]{4})/i);
|
||||
if (uuidMatch) {
|
||||
uuid = uuidMatch[1].toLowerCase();
|
||||
}
|
||||
} else {
|
||||
comment = parts[0] || "";
|
||||
const metadata = parts.slice(1).join("|").trim();
|
||||
|
||||
const logsMatch = metadata.match(/logsEnabled:\s*(true|false)/i);
|
||||
if (logsMatch) {
|
||||
logsEnabled = logsMatch[1].toLowerCase() === "true";
|
||||
}
|
||||
|
||||
const uuidMatch = metadata.match(/id:\s*([a-z0-9]{4}-[a-z0-9]{4})/i);
|
||||
if (uuidMatch) {
|
||||
uuid = uuidMatch[1].toLowerCase();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const logsMatch = commentText.match(/logsEnabled:\s*(true|false)/i);
|
||||
|
||||
@@ -87,7 +87,7 @@ export async function DELETE(
|
||||
if (authError) return authError;
|
||||
|
||||
try {
|
||||
const result = await removeCronJob(params.id);
|
||||
const result = await removeCronJob({ id: params.id, schedule: "", command: "", user: "" });
|
||||
|
||||
if (result.success) {
|
||||
return NextResponse.json(result);
|
||||
|
||||
@@ -76,6 +76,24 @@
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.overflow-y-auto {
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.overflow-y-auto::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
.overflow-y-auto::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
.overflow-y-auto::-webkit-scrollbar-thumb {
|
||||
background-color: hsl(var(--primary) / 0.8);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.overflow-y-auto::-webkit-scrollbar-thumb:hover {
|
||||
background-color: hsl(var(--primary) / 0.1);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use server';
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
import { LoginForm } from "@/app/_components/FeatureComponents/LoginForm/LoginForm";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user