Skip to content

Commit 850491b

Browse files
authored
Merge pull request #141 from Kaguya-19/feat/setting-cron
feat(ui): add cron settings section
2 parents 0cfc4be + b0fbb5a commit 850491b

3 files changed

Lines changed: 98 additions & 2 deletions

File tree

ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
ChevronLeft,
1010
ChevronDown,
1111
ChevronRight,
12+
Clock,
1213
Database,
1314
FileCog,
1415
FolderOpen,
@@ -128,6 +129,11 @@ type PilotDeckConfig = {
128129
};
129130
projects?: Record<string, { enabled?: boolean }>;
130131
};
132+
cron?: {
133+
enabled?: boolean;
134+
timezone?: string;
135+
maxConcurrentRuns?: number;
136+
};
131137
customEnv?: Record<string, string>;
132138
router?: {
133139
enabled?: boolean;
@@ -179,13 +185,14 @@ type PilotDeckConfig = {
179185
};
180186
};
181187

182-
type SectionId = 'models' | 'agents' | 'memory' | 'tools' | 'router' | 'gateway' | 'customEnv' | 'alwaysOn' | 'advanced';
188+
type SectionId = 'models' | 'agents' | 'memory' | 'tools' | 'router' | 'gateway' | 'customEnv' | 'alwaysOn' | 'cron' | 'advanced';
183189

184190
const SECTIONS: Array<{ id: SectionId; labelKey: string; descriptionKey: string }> = [
185191
{ id: 'advanced', labelKey: 'runtime', descriptionKey: 'runtime' },
186192
{ id: 'models', labelKey: 'models', descriptionKey: 'models' },
187193
{ id: 'agents', labelKey: 'agents', descriptionKey: 'agents' },
188194
{ id: 'alwaysOn', labelKey: 'alwaysOn', descriptionKey: 'alwaysOn' },
195+
{ id: 'cron', labelKey: 'cron', descriptionKey: 'cron' },
189196
{ id: 'memory', labelKey: 'memory', descriptionKey: 'memory' },
190197
{ id: 'tools', labelKey: 'tools', descriptionKey: 'tools' },
191198
{ id: 'router', labelKey: 'router', descriptionKey: 'router' },
@@ -195,7 +202,7 @@ const SECTIONS: Array<{ id: SectionId; labelKey: string; descriptionKey: string
195202

196203
const SECTION_GROUPS: Array<{ id: 'basic' | 'features' | 'advanced'; sections: SectionId[] }> = [
197204
{ id: 'basic', sections: ['models', 'agents'] },
198-
{ id: 'features', sections: ['router', 'memory', 'tools', 'alwaysOn', 'gateway'] },
205+
{ id: 'features', sections: ['router', 'memory', 'tools', 'alwaysOn', 'cron', 'gateway'] },
199206
{ id: 'advanced', sections: ['advanced', 'customEnv'] },
200207
];
201208

@@ -206,6 +213,7 @@ const SECTION_ICONS: Record<SectionId, LucideIcon> = {
206213
memory: Brain,
207214
tools: Search,
208215
alwaysOn: Zap,
216+
cron: Clock,
209217
gateway: Wifi,
210218
advanced: Server,
211219
customEnv: FileCog,
@@ -1744,6 +1752,53 @@ function AlwaysOnSection({
17441752
);
17451753
}
17461754

1755+
function CronSection({ config, onChange }: { config: PilotDeckConfig; onChange: (next: PilotDeckConfig) => void }) {
1756+
const { t } = useTranslation('settings');
1757+
const cron = config.cron ?? {};
1758+
const enabled = cron.enabled !== false;
1759+
1760+
return (
1761+
<SettingsSection
1762+
title={t('pilotDeckConfig.panels.cron.title')}
1763+
description={t('pilotDeckConfig.panels.cron.description')}
1764+
>
1765+
<SettingsCard divided>
1766+
<SettingsRow
1767+
label={t('pilotDeckConfig.panels.cron.enabled.label')}
1768+
description={t('pilotDeckConfig.panels.cron.enabled.description')}
1769+
>
1770+
<SettingsToggle
1771+
checked={enabled}
1772+
ariaLabel={t('pilotDeckConfig.panels.cron.enabled.label')}
1773+
onChange={(value) => onChange(patch(config, ['cron', 'enabled'], value))}
1774+
/>
1775+
</SettingsRow>
1776+
<FormRow
1777+
label={t('pilotDeckConfig.panels.cron.timezone.label')}
1778+
description={t('pilotDeckConfig.panels.cron.timezone.description')}
1779+
>
1780+
<TextInput
1781+
value={cron.timezone}
1782+
placeholder="Asia/Shanghai"
1783+
monospace
1784+
onChange={(value) => onChange(patch(config, ['cron', 'timezone'], value || undefined))}
1785+
/>
1786+
</FormRow>
1787+
<FormRow
1788+
label={t('pilotDeckConfig.panels.cron.maxConcurrentRuns.label')}
1789+
description={t('pilotDeckConfig.panels.cron.maxConcurrentRuns.description')}
1790+
>
1791+
<NumberInput
1792+
value={cron.maxConcurrentRuns}
1793+
placeholder="2"
1794+
onChange={(value) => onChange(patch(config, ['cron', 'maxConcurrentRuns'], value))}
1795+
/>
1796+
</FormRow>
1797+
</SettingsCard>
1798+
</SettingsSection>
1799+
);
1800+
}
1801+
17471802
function MemorySection({ config, onChange }: { config: PilotDeckConfig; onChange: (next: PilotDeckConfig) => void }) {
17481803
const { t } = useTranslation('settings');
17491804
const m = config.memory ?? {};
@@ -3188,6 +3243,7 @@ export default function PilotDeckConfigTab({ projects = [] }: { projects?: Setti
31883243
{activeSection === 'gateway' && <GatewaySection config={parsedConfig} onChange={onFormChange} />}
31893244
{activeSection === 'customEnv' && <CustomEnvSection config={parsedConfig} onChange={onFormChange} />}
31903245
{activeSection === 'alwaysOn' && <AlwaysOnSection config={parsedConfig} projects={projects} onChange={onFormChange} />}
3246+
{activeSection === 'cron' && <CronSection config={parsedConfig} onChange={onFormChange} />}
31913247
{activeSection === 'advanced' && <ServiceSection config={parsedConfig} onChange={onFormChange} />}
31923248
</div>
31933249
</div>

ui/src/i18n/locales/en/settings.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,10 @@
628628
"label": "Always-On",
629629
"description": "Automatic discovery and workspace opt-in"
630630
},
631+
"cron": {
632+
"label": "Cron",
633+
"description": "Scheduled background task runtime"
634+
},
631635
"memory": {
632636
"label": "Memory",
633637
"description": "PilotDeck memory service"
@@ -779,6 +783,22 @@
779783
"empty": "No recognized projects yet. Add or open a workspace first."
780784
}
781785
},
786+
"cron": {
787+
"title": "Cron",
788+
"description": "Configure the background scheduler used by Cron jobs. Create and manage jobs from Always-On > Plans & Cron Jobs.",
789+
"enabled": {
790+
"label": "Enabled",
791+
"description": "Master switch for scheduled Cron background tasks."
792+
},
793+
"timezone": {
794+
"label": "Timezone",
795+
"description": "IANA timezone used as the scheduler default."
796+
},
797+
"maxConcurrentRuns": {
798+
"label": "Max concurrent runs",
799+
"description": "Maximum number of Cron runs that may execute at the same time."
800+
}
801+
},
782802
"memory": {
783803
"title": "Memory",
784804
"description": "Configure the model used for memory indexing and Dream.",

ui/src/i18n/locales/zh-CN/settings.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,10 @@
628628
"label": "常驻",
629629
"description": "自动发现和工作区启用设置"
630630
},
631+
"cron": {
632+
"label": "Cron",
633+
"description": "定时后台任务运行时"
634+
},
631635
"memory": {
632636
"label": "记忆",
633637
"description": "PilotDeck 记忆服务"
@@ -779,6 +783,22 @@
779783
"empty": "尚未识别到项目。请先添加或打开一个工作区。"
780784
}
781785
},
786+
"cron": {
787+
"title": "Cron",
788+
"description": "配置 Cron 任务使用的后台调度器。任务创建和管理仍在 Always-On > Plans & Cron Jobs 中完成。",
789+
"enabled": {
790+
"label": "启用",
791+
"description": "定时 Cron 后台任务的总开关。"
792+
},
793+
"timezone": {
794+
"label": "时区",
795+
"description": "调度器默认使用的 IANA 时区。"
796+
},
797+
"maxConcurrentRuns": {
798+
"label": "最大并发运行数",
799+
"description": "同一时间允许执行的 Cron 运行数量上限。"
800+
}
801+
},
782802
"memory": {
783803
"title": "记忆",
784804
"description": "配置记忆索引与 Dream 使用的模型。",

0 commit comments

Comments
 (0)