multica/apps/desktop/electron/ipc/cron.ts
Jiang Bohan a8dd9f2bbb feat(desktop): add Cron Jobs management page
- Add "Cron" tab to navigation bar with Time04Icon
- Add /crons route with CronsPage component
- Add cron IPC handlers (list, toggle, remove) in electron/ipc/cron.ts
- Expose cron API in preload.ts for renderer process
- Add useCronJobs hook for fetching and managing jobs
- Add CronJobList component with status badges, toggle switches,
  delete buttons, relative time display, and empty state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:16:33 +08:00

68 lines
1.9 KiB
TypeScript

/**
* Cron IPC handlers for Electron main process.
*
* These handlers expose CronService operations to the renderer process
* for the Cron Jobs management page.
*/
import { ipcMain } from 'electron'
import { getCronService, formatSchedule } from '../../../../src/cron/index.js'
/**
* Register all Cron-related IPC handlers.
*/
export function registerCronIpcHandlers(): void {
/**
* List all cron jobs with formatted display fields.
*/
ipcMain.handle('cron:list', async () => {
const service = getCronService()
const jobs = service.list()
return jobs.map((job) => ({
id: job.id,
name: job.name,
description: job.description,
enabled: job.enabled,
schedule: formatSchedule(job.schedule),
sessionTarget: job.sessionTarget,
nextRunAt: job.state.nextRunAtMs ? new Date(job.state.nextRunAtMs).toISOString() : null,
lastStatus: job.state.lastStatus ?? null,
lastRunAt: job.state.lastRunAtMs ? new Date(job.state.lastRunAtMs).toISOString() : null,
lastDurationMs: job.state.lastDurationMs ?? null,
lastError: job.state.lastError ?? null,
}))
})
/**
* Toggle a cron job's enabled status.
*/
ipcMain.handle('cron:toggle', async (_event, jobId: string) => {
const service = getCronService()
const job = service.get(jobId)
if (!job) {
return { error: `Job not found: ${jobId}` }
}
const updated = service.update(jobId, { enabled: !job.enabled })
if (!updated) {
return { error: `Failed to update job: ${jobId}` }
}
return {
id: updated.id,
enabled: updated.enabled,
}
})
/**
* Remove a cron job.
*/
ipcMain.handle('cron:remove', async (_event, jobId: string) => {
const service = getCronService()
const removed = service.remove(jobId)
if (!removed) {
return { error: `Job not found: ${jobId}` }
}
return { ok: true }
})
}