From b0fbb5a35500e4f2d8cb2a53006ad54d48cf4c26 Mon Sep 17 00:00:00 2001 From: Kaguya-19 Date: Wed, 3 Jun 2026 12:12:42 +0800 Subject: [PATCH] feat(ui): add cron settings section --- .../settings/view/tabs/PilotDeckConfigTab.tsx | 60 ++++++++++++++++++- ui/src/i18n/locales/en/settings.json | 20 +++++++ ui/src/i18n/locales/zh-CN/settings.json | 20 +++++++ 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx b/ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx index d13f8937..6f88c9e1 100644 --- a/ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx +++ b/ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx @@ -9,6 +9,7 @@ import { ChevronLeft, ChevronDown, ChevronRight, + Clock, Database, FileCog, FolderOpen, @@ -128,6 +129,11 @@ type PilotDeckConfig = { }; projects?: Record; }; + cron?: { + enabled?: boolean; + timezone?: string; + maxConcurrentRuns?: number; + }; customEnv?: Record; router?: { enabled?: boolean; @@ -179,13 +185,14 @@ type PilotDeckConfig = { }; }; -type SectionId = 'models' | 'agents' | 'memory' | 'tools' | 'router' | 'gateway' | 'customEnv' | 'alwaysOn' | 'advanced'; +type SectionId = 'models' | 'agents' | 'memory' | 'tools' | 'router' | 'gateway' | 'customEnv' | 'alwaysOn' | 'cron' | 'advanced'; const SECTIONS: Array<{ id: SectionId; labelKey: string; descriptionKey: string }> = [ { id: 'advanced', labelKey: 'runtime', descriptionKey: 'runtime' }, { id: 'models', labelKey: 'models', descriptionKey: 'models' }, { id: 'agents', labelKey: 'agents', descriptionKey: 'agents' }, { id: 'alwaysOn', labelKey: 'alwaysOn', descriptionKey: 'alwaysOn' }, + { id: 'cron', labelKey: 'cron', descriptionKey: 'cron' }, { id: 'memory', labelKey: 'memory', descriptionKey: 'memory' }, { id: 'tools', labelKey: 'tools', descriptionKey: 'tools' }, { id: 'router', labelKey: 'router', descriptionKey: 'router' }, @@ -195,7 +202,7 @@ const SECTIONS: Array<{ id: SectionId; labelKey: string; descriptionKey: string const SECTION_GROUPS: Array<{ id: 'basic' | 'features' | 'advanced'; sections: SectionId[] }> = [ { id: 'basic', sections: ['models', 'agents'] }, - { id: 'features', sections: ['router', 'memory', 'tools', 'alwaysOn', 'gateway'] }, + { id: 'features', sections: ['router', 'memory', 'tools', 'alwaysOn', 'cron', 'gateway'] }, { id: 'advanced', sections: ['advanced', 'customEnv'] }, ]; @@ -206,6 +213,7 @@ const SECTION_ICONS: Record = { memory: Brain, tools: Search, alwaysOn: Zap, + cron: Clock, gateway: Wifi, advanced: Server, customEnv: FileCog, @@ -1744,6 +1752,53 @@ function AlwaysOnSection({ ); } +function CronSection({ config, onChange }: { config: PilotDeckConfig; onChange: (next: PilotDeckConfig) => void }) { + const { t } = useTranslation('settings'); + const cron = config.cron ?? {}; + const enabled = cron.enabled !== false; + + return ( + + + + onChange(patch(config, ['cron', 'enabled'], value))} + /> + + + onChange(patch(config, ['cron', 'timezone'], value || undefined))} + /> + + + onChange(patch(config, ['cron', 'maxConcurrentRuns'], value))} + /> + + + + ); +} + function MemorySection({ config, onChange }: { config: PilotDeckConfig; onChange: (next: PilotDeckConfig) => void }) { const { t } = useTranslation('settings'); const m = config.memory ?? {}; @@ -3188,6 +3243,7 @@ export default function PilotDeckConfigTab({ projects = [] }: { projects?: Setti {activeSection === 'gateway' && } {activeSection === 'customEnv' && } {activeSection === 'alwaysOn' && } + {activeSection === 'cron' && } {activeSection === 'advanced' && } diff --git a/ui/src/i18n/locales/en/settings.json b/ui/src/i18n/locales/en/settings.json index 36a451c2..4e93d7f2 100644 --- a/ui/src/i18n/locales/en/settings.json +++ b/ui/src/i18n/locales/en/settings.json @@ -628,6 +628,10 @@ "label": "Always-On", "description": "Automatic discovery and workspace opt-in" }, + "cron": { + "label": "Cron", + "description": "Scheduled background task runtime" + }, "memory": { "label": "Memory", "description": "PilotDeck memory service" @@ -779,6 +783,22 @@ "empty": "No recognized projects yet. Add or open a workspace first." } }, + "cron": { + "title": "Cron", + "description": "Configure the background scheduler used by Cron jobs. Create and manage jobs from Always-On > Plans & Cron Jobs.", + "enabled": { + "label": "Enabled", + "description": "Master switch for scheduled Cron background tasks." + }, + "timezone": { + "label": "Timezone", + "description": "IANA timezone used as the scheduler default." + }, + "maxConcurrentRuns": { + "label": "Max concurrent runs", + "description": "Maximum number of Cron runs that may execute at the same time." + } + }, "memory": { "title": "Memory", "description": "Configure the model used for memory indexing and Dream.", diff --git a/ui/src/i18n/locales/zh-CN/settings.json b/ui/src/i18n/locales/zh-CN/settings.json index 75e9c564..72bd9089 100644 --- a/ui/src/i18n/locales/zh-CN/settings.json +++ b/ui/src/i18n/locales/zh-CN/settings.json @@ -628,6 +628,10 @@ "label": "常驻", "description": "自动发现和工作区启用设置" }, + "cron": { + "label": "Cron", + "description": "定时后台任务运行时" + }, "memory": { "label": "记忆", "description": "PilotDeck 记忆服务" @@ -779,6 +783,22 @@ "empty": "尚未识别到项目。请先添加或打开一个工作区。" } }, + "cron": { + "title": "Cron", + "description": "配置 Cron 任务使用的后台调度器。任务创建和管理仍在 Always-On > Plans & Cron Jobs 中完成。", + "enabled": { + "label": "启用", + "description": "定时 Cron 后台任务的总开关。" + }, + "timezone": { + "label": "时区", + "description": "调度器默认使用的 IANA 时区。" + }, + "maxConcurrentRuns": { + "label": "最大并发运行数", + "description": "同一时间允许执行的 Cron 运行数量上限。" + } + }, "memory": { "title": "记忆", "description": "配置记忆索引与 Dream 使用的模型。",