import { html, nothing } from 'lit'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; import { LightElement } from '../../lib/base.js'; import { toString as cronToString } from 'cronstrue'; import { formatDate } from './utils.js'; import { t } from '../../lib/i18n.js'; export class CronJobsSection extends LightElement { static properties = { _jobs: { state: true }, _error: { state: true }, }; constructor() { super(); this._jobs = []; this._error = null; } connectedCallback() { super.connectedCallback(); this.__onLocaleChanged = () => this.requestUpdate(); window.addEventListener('locale-changed', this.__onLocaleChanged); } disconnectedCallback() { window.removeEventListener('locale-changed', this.__onLocaleChanged); super.disconnectedCallback(); } async load() { this._error = null; try { const res = await fetch('/api/cron/jobs'); if (!res.ok) throw new Error(`HTTP ${res.status}`); const allJobs = await res.json(); this._jobs = allJobs.filter(j => j.kind === 'cron' && !j.single_run); } catch (e) { this._error = e.message; } } async _delete(job) { if (!confirm(t('cron.confirm.delete', { title: job.title }))) return; try { const res = await fetch(`/api/cron/jobs/${job.id}`, { method: 'DELETE' }); if (!res.ok) throw new Error(await res.text()); await this.load(); } catch (e) { this._error = e.message; } } async _toggle(job) { try { const res = await fetch(`/api/cron/jobs/${job.id}/toggle`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled: !job.enabled }), }); if (!res.ok) throw new Error(await res.text()); await this.load(); } catch (e) { this._error = e.message; } } _statusBadge(job) { if (job.running_session_id != null) return html`${t('cron.badge.running')}`; if (!job.enabled) return html`${t('cron.badge.disabled')}`; return html`${t('cron.badge.idle')}`; } _renderCard(job) { return html`
${job.cron}
${t('cron.empty.title')} ${unsafeHTML(t('cron.empty.hint'))}