Skip to content

Commit 8faf4d2

Browse files
committed
send fixes to develop for automatic ID assignation
1 parent 1fd2689 commit 8faf4d2

10 files changed

Lines changed: 218 additions & 127 deletions

File tree

app/_components/FeatureComponents/Cronjobs/CronJobList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ export const CronJobList = ({ cronJobs, scripts }: CronJobListProps) => {
215215
onNewTaskClick={() => setIsNewCronModalOpen(true)}
216216
/>
217217
) : (
218-
<div className="space-y-3">
218+
<div className="space-y-3 max-h-[60vh] overflow-y-auto">
219219
{filteredJobs.map((job) => (
220220
<CronJobItem
221221
key={job.id}

app/_components/FeatureComponents/Cronjobs/helpers/index.tsx

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,27 +69,33 @@ export const refreshJobErrors = (
6969
setJobErrors(errors);
7070
};
7171

72-
export const handleDelete = async (id: string, props: HandlerProps) => {
72+
export const handleDelete = async (job: CronJob, props: HandlerProps) => {
7373
const {
7474
setDeletingId,
7575
setIsDeleteModalOpen,
7676
setJobToDelete,
7777
refreshJobErrors,
7878
} = props;
7979

80-
setDeletingId(id);
80+
setDeletingId(job.id);
8181
try {
82-
const result = await removeCronJob(id);
82+
const result = await removeCronJob({
83+
id: job.id,
84+
schedule: job.schedule,
85+
command: job.command,
86+
comment: job.comment,
87+
user: job.user,
88+
});
8389
if (result.success) {
8490
showToast("success", "Cron job deleted successfully");
8591
} else {
86-
const errorId = `delete-${id}-${Date.now()}`;
92+
const errorId = `delete-${job.id}-${Date.now()}`;
8793
const jobError: JobError = {
8894
id: errorId,
8995
title: "Failed to delete cron job",
9096
message: result.message,
9197
timestamp: new Date().toISOString(),
92-
jobId: id,
98+
jobId: job.id,
9399
};
94100
setJobError(jobError);
95101
refreshJobErrors();
@@ -107,14 +113,14 @@ export const handleDelete = async (id: string, props: HandlerProps) => {
107113
);
108114
}
109115
} catch (error: any) {
110-
const errorId = `delete-${id}-${Date.now()}`;
116+
const errorId = `delete-${job.id}-${Date.now()}`;
111117
const jobError: JobError = {
112118
id: errorId,
113119
title: "Failed to delete cron job",
114120
message: error.message || "Please try again later.",
115121
details: error.stack,
116122
timestamp: new Date().toISOString(),
117-
jobId: id,
123+
jobId: job.id,
118124
};
119125
setJobError(jobError);
120126
showToast(
@@ -158,9 +164,15 @@ export const handleClone = async (newComment: string, props: HandlerProps) => {
158164
}
159165
};
160166

161-
export const handlePause = async (id: string) => {
167+
export const handlePause = async (job: any) => {
162168
try {
163-
const result = await pauseCronJobAction(id);
169+
const result = await pauseCronJobAction({
170+
id: job.id,
171+
schedule: job.schedule,
172+
command: job.command,
173+
comment: job.comment,
174+
user: job.user,
175+
});
164176
if (result.success) {
165177
showToast("success", "Cron job paused successfully");
166178
} else {
@@ -171,9 +183,16 @@ export const handlePause = async (id: string) => {
171183
}
172184
};
173185

174-
export const handleToggleLogging = async (id: string) => {
186+
export const handleToggleLogging = async (job: any) => {
175187
try {
176-
const result = await toggleCronJobLogging(id);
188+
const result = await toggleCronJobLogging({
189+
id: job.id,
190+
schedule: job.schedule,
191+
command: job.command,
192+
comment: job.comment,
193+
user: job.user,
194+
logsEnabled: job.logsEnabled,
195+
});
177196
if (result.success) {
178197
showToast("success", result.message);
179198
} else {
@@ -185,9 +204,15 @@ export const handleToggleLogging = async (id: string) => {
185204
}
186205
};
187206

188-
export const handleResume = async (id: string) => {
207+
export const handleResume = async (job: any) => {
189208
try {
190-
const result = await resumeCronJobAction(id);
209+
const result = await resumeCronJobAction({
210+
id: job.id,
211+
schedule: job.schedule,
212+
command: job.command,
213+
comment: job.comment,
214+
user: job.user,
215+
});
191216
if (result.success) {
192217
showToast("success", "Cron job resumed successfully");
193218
} else {
@@ -401,9 +426,9 @@ export const handleNewCronSubmit = async (
401426
}
402427
};
403428

404-
export const handleBackup = async (id: string) => {
429+
export const handleBackup = async (job: any) => {
405430
try {
406-
const result = await backupCronJob(id);
431+
const result = await backupCronJob(job);
407432
if (result.success) {
408433
showToast("success", "Job backed up successfully");
409434
} else {

app/_hooks/useCronJobState.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,28 @@ export const useCronJobState = ({ cronJobs, scripts }: CronJobListProps) => {
127127
};
128128

129129
const handleDeleteLocal = async (id: string) => {
130-
await handleDelete(id, getHelperState());
130+
const job = cronJobs.find(j => j.id === id);
131+
if (job) {
132+
await handleDelete(job, getHelperState());
133+
}
131134
};
132135

133136
const handleCloneLocal = async (newComment: string) => {
134137
await handleClone(newComment, getHelperState());
135138
};
136139

137140
const handlePauseLocal = async (id: string) => {
138-
await handlePause(id);
141+
const job = cronJobs.find(j => j.id === id);
142+
if (job) {
143+
await handlePause(job);
144+
}
139145
};
140146

141147
const handleResumeLocal = async (id: string) => {
142-
await handleResume(id);
148+
const job = cronJobs.find(j => j.id === id);
149+
if (job) {
150+
await handleResume(job);
151+
}
143152
};
144153

145154
const handleRunLocal = async (id: string) => {
@@ -149,7 +158,10 @@ export const useCronJobState = ({ cronJobs, scripts }: CronJobListProps) => {
149158
};
150159

151160
const handleToggleLoggingLocal = async (id: string) => {
152-
await handleToggleLogging(id);
161+
const job = cronJobs.find(j => j.id === id);
162+
if (job) {
163+
await handleToggleLogging(job);
164+
}
153165
};
154166

155167
const handleViewLogs = (job: CronJob) => {
@@ -187,7 +199,10 @@ export const useCronJobState = ({ cronJobs, scripts }: CronJobListProps) => {
187199
};
188200

189201
const handleBackupLocal = async (id: string) => {
190-
await handleBackup(id);
202+
const job = cronJobs.find(j => j.id === id);
203+
if (job) {
204+
await handleBackup(job);
205+
}
191206
};
192207

193208
return {

app/_server/actions/cronjobs/index.ts

Lines changed: 72 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,27 @@
33
import {
44
getCronJobs,
55
addCronJob,
6-
deleteCronJob,
7-
updateCronJob,
8-
pauseCronJob,
9-
resumeCronJob,
106
cleanupCrontab,
7+
readUserCrontab,
8+
writeUserCrontab,
9+
findJobIndex,
10+
updateCronJob,
1111
type CronJob,
1212
} from "@/app/_utils/cronjob-utils";
13-
import { getAllTargetUsers, getUserInfo } from "@/app/_utils/crontab-utils";
13+
import { getAllTargetUsers } from "@/app/_utils/crontab-utils";
1414
import { revalidatePath } from "next/cache";
1515
import { getScriptPathForCron } from "@/app/_server/actions/scripts";
16-
import { exec } from "child_process";
17-
import { promisify } from "util";
1816
import { isDocker } from "@/app/_server/actions/global";
1917
import {
2018
runJobSynchronously,
2119
runJobInBackground,
2220
} from "@/app/_utils/job-execution-utils";
23-
24-
const execAsync = promisify(exec);
21+
import {
22+
pauseJobInLines,
23+
resumeJobInLines,
24+
deleteJobInLines,
25+
} from "@/app/_utils/line-manipulation-utils";
26+
import { cleanCrontabContent } from "@/app/_utils/files-manipulation-utils";
2527

2628
export const fetchCronJobs = async (): Promise<CronJob[]> => {
2729
try {
@@ -90,10 +92,22 @@ export const createCronJob = async (
9092
};
9193

9294
export const removeCronJob = async (
93-
id: string
95+
jobData: { id: string; schedule: string; command: string; comment?: string; user: string }
9496
): Promise<{ success: boolean; message: string; details?: string }> => {
9597
try {
96-
const success = await deleteCronJob(id);
98+
const cronContent = await readUserCrontab(jobData.user);
99+
const lines = cronContent.split("\n");
100+
101+
const jobIndex = findJobIndex(jobData, lines, jobData.user);
102+
103+
if (jobIndex === -1) {
104+
return { success: false, message: "Cron job not found in crontab" };
105+
}
106+
107+
const newCronEntries = deleteJobInLines(lines, jobIndex);
108+
const newCron = await cleanCrontabContent(newCronEntries.join("\n"));
109+
const success = await writeUserCrontab(jobData.user, newCron);
110+
97111
if (success) {
98112
revalidatePath("/");
99113
return { success: true, message: "Cron job deleted successfully" };
@@ -124,8 +138,15 @@ export const editCronJob = async (
124138
return { success: false, message: "Missing required fields" };
125139
}
126140

141+
const cronJobs = await getCronJobs(false);
142+
const job = cronJobs.find((j) => j.id === id);
143+
144+
if (!job) {
145+
return { success: false, message: "Cron job not found" };
146+
}
147+
127148
const success = await updateCronJob(
128-
id,
149+
job,
129150
schedule,
130151
command,
131152
comment,
@@ -152,7 +173,7 @@ export const cloneCronJob = async (
152173
newComment: string
153174
): Promise<{ success: boolean; message: string; details?: string }> => {
154175
try {
155-
const cronJobs = await getCronJobs();
176+
const cronJobs = await getCronJobs(false);
156177
const originalJob = cronJobs.find((job) => job.id === id);
157178

158179
if (!originalJob) {
@@ -183,10 +204,22 @@ export const cloneCronJob = async (
183204
};
184205

185206
export const pauseCronJobAction = async (
186-
id: string
207+
jobData: { id: string; schedule: string; command: string; comment?: string; user: string }
187208
): Promise<{ success: boolean; message: string; details?: string }> => {
188209
try {
189-
const success = await pauseCronJob(id);
210+
const cronContent = await readUserCrontab(jobData.user);
211+
const lines = cronContent.split("\n");
212+
213+
const jobIndex = findJobIndex(jobData, lines, jobData.user);
214+
215+
if (jobIndex === -1) {
216+
return { success: false, message: "Cron job not found in crontab" };
217+
}
218+
219+
const newCronEntries = pauseJobInLines(lines, jobIndex, jobData.id);
220+
const newCron = await cleanCrontabContent(newCronEntries.join("\n"));
221+
const success = await writeUserCrontab(jobData.user, newCron);
222+
190223
if (success) {
191224
revalidatePath("/");
192225
return { success: true, message: "Cron job paused successfully" };
@@ -204,10 +237,22 @@ export const pauseCronJobAction = async (
204237
};
205238

206239
export const resumeCronJobAction = async (
207-
id: string
240+
jobData: { id: string; schedule: string; command: string; comment?: string; user: string }
208241
): Promise<{ success: boolean; message: string; details?: string }> => {
209242
try {
210-
const success = await resumeCronJob(id);
243+
const cronContent = await readUserCrontab(jobData.user);
244+
const lines = cronContent.split("\n");
245+
246+
const jobIndex = findJobIndex(jobData, lines, jobData.user);
247+
248+
if (jobIndex === -1) {
249+
return { success: false, message: "Cron job not found in crontab" };
250+
}
251+
252+
const newCronEntries = resumeJobInLines(lines, jobIndex, jobData.id);
253+
const newCron = await cleanCrontabContent(newCronEntries.join("\n"));
254+
const success = await writeUserCrontab(jobData.user, newCron);
255+
211256
if (success) {
212257
revalidatePath("/");
213258
return { success: true, message: "Cron job resumed successfully" };
@@ -257,23 +302,16 @@ export const cleanupCrontabAction = async (): Promise<{
257302
};
258303

259304
export const toggleCronJobLogging = async (
260-
id: string
305+
jobData: { id: string; schedule: string; command: string; comment?: string; user: string; logsEnabled?: boolean }
261306
): Promise<{ success: boolean; message: string; details?: string }> => {
262307
try {
263-
const cronJobs = await getCronJobs();
264-
const job = cronJobs.find((j) => j.id === id);
265-
266-
if (!job) {
267-
return { success: false, message: "Cron job not found" };
268-
}
269-
270-
const newLogsEnabled = !job.logsEnabled;
308+
const newLogsEnabled = !jobData.logsEnabled;
271309

272310
const success = await updateCronJob(
273-
id,
274-
job.schedule,
275-
job.command,
276-
job.comment || "",
311+
jobData,
312+
jobData.schedule,
313+
jobData.command,
314+
jobData.comment || "",
277315
newLogsEnabled
278316
);
279317

@@ -309,7 +347,7 @@ export const runCronJob = async (
309347
mode?: "sync" | "async";
310348
}> => {
311349
try {
312-
const cronJobs = await getCronJobs();
350+
const cronJobs = await getCronJobs(false);
313351
const job = cronJobs.find((j) => j.id === id);
314352

315353
if (!job) {
@@ -356,7 +394,7 @@ export const executeJob = async (
356394
mode?: "sync" | "async";
357395
}> => {
358396
try {
359-
const cronJobs = await getCronJobs();
397+
const cronJobs = await getCronJobs(false);
360398
const job = cronJobs.find((j) => j.id === id);
361399

362400
if (!job) {
@@ -388,13 +426,13 @@ export const executeJob = async (
388426
};
389427

390428
export const backupCronJob = async (
391-
id: string
429+
job: CronJob
392430
): Promise<{ success: boolean; message: string; details?: string }> => {
393431
try {
394432
const {
395433
backupJobToFile,
396434
} = await import("@/app/_utils/backup-utils");
397-
const success = await backupJobToFile(id);
435+
const success = await backupJobToFile(job);
398436
if (success) {
399437
return { success: true, message: "Cron job backed up successfully" };
400438
} else {

0 commit comments

Comments
 (0)