diff --git a/static/i18n.js b/static/i18n.js index 4055d47a9..c46f3aa91 100644 --- a/static/i18n.js +++ b/static/i18n.js @@ -1591,6 +1591,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Weekly', cron_schedule_preset_monthly: 'Monthly', cron_schedule_preset_custom: 'Custom', + cron_schedule_hour_label: 'Hour', + cron_schedule_minute_label: 'Minute', + cron_schedule_weekday_label: 'Weekday (0-6, Sun-Sat)', + cron_schedule_month_day_label: 'Day', + cron_schedule_time_hint: 'Time is server time; cron runs server-side.', cron_schedule_hint: "Use 'every 1h' or a cron expression for recurring jobs. Bare durations like '30m' run once.", cron_schedule_once_warning: "Duration forms like '30m' run once and are removed after running. Use 'every 30m' to keep a recurring job.", cron_prompt_label: 'Prompt', @@ -3256,6 +3261,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Ogni settimana', cron_schedule_preset_monthly: 'Ogni mese', cron_schedule_preset_custom: 'Personalizzato', + cron_schedule_hour_label: 'Ora', + cron_schedule_minute_label: 'Minuto', + cron_schedule_weekday_label: 'Giorno della settimana (0-6, Dom-Sab)', + cron_schedule_month_day_label: 'Giorno', + cron_schedule_time_hint: 'L\'ora è quella del server; cron viene eseguito lato server.', cron_schedule_hint: 'Usa \'every 1h\' o un\'espressione cron per job ricorrenti. Durate semplici come \'30m\' vengono eseguite una volta sola.', cron_schedule_once_warning: 'Forme di durata come \'30m\' vengono eseguite una volta e rimosse dopo l\'esecuzione. Usa \'every 30m\' per mantenere un job ricorrente.', cron_prompt_label: 'Prompt', @@ -4929,6 +4939,11 @@ const LOCALES = { cron_schedule_preset_weekly: '毎週', cron_schedule_preset_monthly: '毎月', cron_schedule_preset_custom: 'カスタム', + cron_schedule_hour_label: '時', + cron_schedule_minute_label: '分', + cron_schedule_weekday_label: '曜日 (0-6, 日-土)', + cron_schedule_month_day_label: '日', + cron_schedule_time_hint: '時刻はサーバー時刻です。cron はサーバー側で実行されます。', cron_schedule_hint: "繰り返し実行には 'every 1h' または Cron 式を使います。'30m' のような期間だけの指定は 1 回だけ実行されます。", cron_schedule_once_warning: "'30m' のような期間指定は 1 回だけ実行され、実行後に削除されます。繰り返すには 'every 30m' を使ってください。", cron_prompt_label: 'プロンプト', @@ -6244,6 +6259,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Еженедельно', cron_schedule_preset_monthly: 'Ежемесячно', cron_schedule_preset_custom: 'Пользовательский', + cron_schedule_hour_label: 'Час', + cron_schedule_minute_label: 'Минута', + cron_schedule_weekday_label: 'День недели (0-6, вс-сб)', + cron_schedule_month_day_label: 'День', + cron_schedule_time_hint: 'Время указано по серверу; cron выполняется на сервере.', cron_schedule_hint: "Для повторяющихся заданий используйте 'every 1h' или cron-выражение. Простые интервалы вроде '30m' выполняются один раз.", cron_schedule_once_warning: "Интервалы вроде '30m' выполняются один раз и удаляются после запуска. Используйте 'every 30m' для повторяющегося задания.", cron_prompt_label: 'Запрос', @@ -7836,6 +7856,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Semanal', cron_schedule_preset_monthly: 'Mensual', cron_schedule_preset_custom: 'Personalizado', + cron_schedule_hour_label: 'Hora', + cron_schedule_minute_label: 'Minuto', + cron_schedule_weekday_label: 'Día de la semana (0-6, dom-sáb)', + cron_schedule_month_day_label: 'Día', + cron_schedule_time_hint: 'La hora es la del servidor; cron se ejecuta del lado del servidor.', cron_schedule_hint: "Usa 'every 1h' o una expresión cron para trabajos recurrentes. Duraciones como '30m' se ejecutan una sola vez.", cron_schedule_once_warning: "Las duraciones como '30m' se ejecutan una vez y se eliminan después de correr. Usa 'every 30m' para mantener un trabajo recurrente.", cron_prompt_label: 'Prompt', @@ -9110,6 +9135,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Wöchentlich', cron_schedule_preset_monthly: 'Monatlich', cron_schedule_preset_custom: 'Benutzerdefiniert', + cron_schedule_hour_label: 'Stunde', + cron_schedule_minute_label: 'Minute', + cron_schedule_weekday_label: 'Wochentag (0-6, So-Sa)', + cron_schedule_month_day_label: 'Tag', + cron_schedule_time_hint: 'Die Zeit ist Serverzeit; cron läuft serverseitig.', cron_schedule_hint: "Für wiederkehrende Aufgaben 'every 1h' oder einen Cron-Ausdruck verwenden. Reine Dauern wie '30m' laufen einmal.", cron_schedule_once_warning: "Dauerangaben wie '30m' laufen einmal und werden nach der Ausführung entfernt. Verwende 'every 30m' für eine wiederkehrende Aufgabe.", cron_prompt_label: 'Prompt', @@ -11056,6 +11086,11 @@ const LOCALES = { cron_schedule_preset_weekly: '每周', cron_schedule_preset_monthly: '每月', cron_schedule_preset_custom: '自定义', + cron_schedule_hour_label: '小时', + cron_schedule_minute_label: '分钟', + cron_schedule_weekday_label: '星期 (0-6,周日-周六)', + cron_schedule_month_day_label: '日期', + cron_schedule_time_hint: '时间以服务器时间为准;cron 在服务器端运行。', cron_schedule_hint: "循环任务请用 'every 1h' 或 Cron 表达式。像 '30m' 这样的裸时长只会运行一次。", cron_schedule_once_warning: "像 '30m' 这样的时长写法只会运行一次,并在运行后移除。要保留循环任务,请使用 'every 30m'。", cron_prompt_label: '提示词', @@ -13023,6 +13058,11 @@ const LOCALES = { cron_schedule_preset_weekly: '每週', cron_schedule_preset_monthly: '每月', cron_schedule_preset_custom: '自訂', + cron_schedule_hour_label: '小時', + cron_schedule_minute_label: '分鐘', + cron_schedule_weekday_label: '星期 (0-6,週日-週六)', + cron_schedule_month_day_label: '日期', + cron_schedule_time_hint: '時間以伺服器時間為準;cron 在伺服器端執行。', cron_schedule_hint: '週期性任務請用「every 1h」或 Cron 表示式。像「30m」這樣的裸時長只會執行一次。', cron_schedule_once_warning: '像「30m」這樣的時長寫法只會執行一次,並在執行後移除。要保留週期性任務,請使用「every 30m」。', cron_prompt_label: '提示', @@ -14429,6 +14469,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Semanal', cron_schedule_preset_monthly: 'Mensal', cron_schedule_preset_custom: 'Personalizado', + cron_schedule_hour_label: 'Hora', + cron_schedule_minute_label: 'Minuto', + cron_schedule_weekday_label: 'Dia da semana (0-6, dom-sáb)', + cron_schedule_month_day_label: 'Dia', + cron_schedule_time_hint: 'O horário usa a hora do servidor; cron roda no servidor.', cron_schedule_hint: "Use 'every 1h' ou uma expressão Cron para tarefas recorrentes. Durações como '30m' rodam uma vez.", cron_schedule_once_warning: "Durações como '30m' rodam uma vez e são removidas após executar. Use 'every 30m' para manter uma tarefa recorrente.", cron_prompt_label: 'Prompt', @@ -16078,6 +16123,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Weekly', cron_schedule_preset_monthly: 'Monthly', cron_schedule_preset_custom: 'Custom', + cron_schedule_hour_label: '시간', + cron_schedule_minute_label: '분', + cron_schedule_weekday_label: '요일 (0-6, 일-토)', + cron_schedule_month_day_label: '일', + cron_schedule_time_hint: '시간은 서버 시간 기준이며 cron은 서버에서 실행됩니다.', cron_schedule_hint: "Use 'every 1h' or a cron expression for recurring jobs. Bare durations like '30m' run once.", cron_schedule_once_warning: "Duration forms like '30m' run once and are removed after running. Use 'every 30m' to keep a recurring job.", cron_prompt_label: 'Prompt', @@ -17819,6 +17869,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Hebdomadaire', cron_schedule_preset_monthly: 'Mensuel', cron_schedule_preset_custom: 'Personnalisé', + cron_schedule_hour_label: 'Heure', + cron_schedule_minute_label: 'Minute', + cron_schedule_weekday_label: 'Jour de la semaine (0-6, dim-sam)', + cron_schedule_month_day_label: 'Jour', + cron_schedule_time_hint: 'L\'heure est celle du serveur; cron s\'exécute côté serveur.', cron_schedule_hint: "Utilisez 'every 1h' ou une expression cron pour les tâches récurrentes. Les durées simples comme '30m' s'exécutent une fois.", cron_schedule_once_warning: "Les formes de durée comme '30m' s'exécutent une fois et sont supprimées après l'exécution. Utilisez 'every 30m' pour conserver une tâche récurrente.", cron_prompt_label: 'Invite', @@ -19392,6 +19447,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Haftalık', cron_schedule_preset_monthly: 'Aylık', cron_schedule_preset_custom: 'Özel', + cron_schedule_hour_label: 'Saat', + cron_schedule_minute_label: 'Dakika', + cron_schedule_weekday_label: 'Haftanın günü (0-6, Paz-Cmt)', + cron_schedule_month_day_label: 'Gün', + cron_schedule_time_hint: 'Saat sunucu saatidir; cron sunucu tarafında çalışır.', cron_schedule_hint: "Use 'every 1h' or a cron expression for recurring jobs. Bare durations like '30m' run once.", cron_schedule_once_warning: "Duration forms like '30m' run once and are removed after running. Use 'every 30m' to keep a recurring job.", cron_prompt_label: 'Çabuk', @@ -21145,6 +21205,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Co tydzień', cron_schedule_preset_monthly: 'Co miesiąc', cron_schedule_preset_custom: 'Niestandardowe', + cron_schedule_hour_label: 'Godzina', + cron_schedule_minute_label: 'Minuta', + cron_schedule_weekday_label: 'Dzień tygodnia (0-6, niedz.-sob.)', + cron_schedule_month_day_label: 'Dzień', + cron_schedule_time_hint: 'Czas jest czasem serwera; cron działa po stronie serwera.', cron_schedule_hint: "Użyj 'every 1h' lub wyrażenia cron dla zadań cyklicznych. Same formy czasu trwania, jak '30m', zostaną uruchomione tylko raz.", cron_schedule_once_warning: 'Formy czasu trwania, takie jak \'30m\', są uruchamiane raz i usuwane po uruchomieniu. Użyj \'every 30m\', aby utrzymać zadanie cykliczne.', cron_prompt_label: 'Monit', @@ -22652,6 +22717,11 @@ const LOCALES = { cron_schedule_preset_weekly: 'Hàng tuần', cron_schedule_preset_monthly: 'Hàng tháng', cron_schedule_preset_custom: 'Tùy chỉnh', + cron_schedule_hour_label: 'Giờ', + cron_schedule_minute_label: 'Phút', + cron_schedule_weekday_label: 'Thứ trong tuần (0-6, CN-T7)', + cron_schedule_month_day_label: 'Ngày', + cron_schedule_time_hint: 'Thời gian dùng giờ máy chủ; cron chạy phía máy chủ.', cron_schedule_hint: "Dùng 'every 1h' hoặc biểu thức cron cho job lặp lại. Các khoảng thời gian đơn như '30m' chỉ chạy một lần.", cron_schedule_once_warning: "Các dạng thời lượng như '30m' chỉ chạy một lần và sẽ bị xóa sau khi chạy. Dùng 'every 30m' để giữ job lặp lại.", cron_prompt_label: 'Prompt', diff --git a/static/panels.js b/static/panels.js index 4a918aa24..b653ed6ff 100644 --- a/static/panels.js +++ b/static/panels.js @@ -507,7 +507,7 @@ function _cronSchedulePresetFieldEl(field) { function _cronSchedulePresetBounds(field) { if (field === 'hour') return { min: 0, max: 23 }; if (field === 'minute') return { min: 0, max: 59 }; - if (field === 'weekday') return { min: 0, max: 7 }; + if (field === 'weekday') return { min: 0, max: 6 }; if (field === 'monthDay') return { min: 1, max: 31 }; return { min: 0, max: 999 }; } @@ -583,8 +583,8 @@ function _cronSchedulePresetValuesForSelection(presetId) { return {}; } -function _cronSchedulePresetValueForSelection(presetId) { - const values = _cronSchedulePresetValuesForSelection(presetId); +function _cronSchedulePresetValueForSelection(presetId, selectedValues) { + const values = selectedValues || _cronSchedulePresetValuesForSelection(presetId); if (presetId === 'hourly') return `${values.minute} * * * *`; if (presetId === 'daily') return `${values.minute} ${values.hour} * * *`; if (presetId === 'weekdays') return `${values.minute} ${values.hour} * * 1-5`; @@ -613,8 +613,8 @@ function _cronSchedulePresetStateForInput(value) { if (hour === '*' && dayOfMonth === '*' && month === '*' && dayOfWeek === '*') { return { presetId: 'hourly', minute }; } - if (_cronSchedulePresetRawFieldInBounds('hour', hour) && dayOfMonth === '*' && month === '*' && _cronSchedulePresetRawFieldInBounds('weekday', dayOfWeek)) { - return { presetId: 'weekly', minute, hour, weekday: dayOfWeek }; + if (_cronSchedulePresetRawFieldInBounds('hour', hour) && dayOfMonth === '*' && month === '*' && (_cronSchedulePresetRawFieldInBounds('weekday', dayOfWeek) || dayOfWeek === '7')) { + return { presetId: 'weekly', minute, hour, weekday: dayOfWeek === '7' ? '0' : dayOfWeek }; } if (_cronSchedulePresetRawFieldInBounds('hour', hour) && _cronSchedulePresetRawFieldInBounds('monthDay', dayOfMonth) && month === '*' && dayOfWeek === '*') { return { presetId: 'monthly', minute, hour, monthDay: dayOfMonth }; @@ -647,9 +647,11 @@ function _applyCronSchedulePresetSelection() { if (!presetEl || !scheduleEl) return; const presetId = presetEl.value; if (presetId !== 'custom') { - scheduleEl.value = _cronSchedulePresetValueForSelection(presetId); - _cronSchedulePresetApplyValues(_cronSchedulePresetValuesForSelection(presetId)); - _syncCronSchedulePresetAndWarning(); + const values = _cronSchedulePresetValuesForSelection(presetId); + _cronSchedulePresetApplyValues(values); + scheduleEl.value = _cronSchedulePresetValueForSelection(presetId, values); + _cronSchedulePresetSyncVisibility(presetId); + _syncCronScheduleWarning(); return; } _cronSchedulePresetSyncVisibility(presetId); @@ -659,15 +661,16 @@ function _applyCronSchedulePresetSelection() { function _initCronSchedulePresetControls() { const presetEl = $('cronFormSchedulePreset'); const scheduleEl = $('cronFormSchedule'); - const presetParams = $('cronFormSchedulePresetParams'); - if (!presetEl || !scheduleEl || !presetParams) return; + if (!presetEl || !scheduleEl) return; presetEl.addEventListener('change', _applyCronSchedulePresetSelection); - ['cronFormScheduleHour', 'cronFormScheduleMinute', 'cronFormScheduleWeekday', 'cronFormScheduleMonthDay'].forEach((id) => { - const el = $(id); - if (!el) return; - el.addEventListener('change', _applyCronSchedulePresetSelection); - el.addEventListener('input', _applyCronSchedulePresetSelection); - }); + if ($('cronFormSchedulePresetParams')) { + ['cronFormScheduleHour', 'cronFormScheduleMinute', 'cronFormScheduleWeekday', 'cronFormScheduleMonthDay'].forEach((id) => { + const el = $(id); + if (!el) return; + el.addEventListener('change', _applyCronSchedulePresetSelection); + el.addEventListener('input', _applyCronSchedulePresetSelection); + }); + } scheduleEl.addEventListener('input', _syncCronSchedulePresetAndWarning); scheduleEl.addEventListener('change', _syncCronSchedulePresetAndWarning); _syncCronSchedulePresetAndWarning(); @@ -1535,13 +1538,13 @@ function _renderCronForm({ name, schedule, prompt, deliver, profile, toast_notif