feat(cron): Enhance scheduled tasks with create/edit dialog and presets

- Add TaskDialog component for creating/editing cron jobs
- Implement schedule presets (every minute, hourly, daily, weekly, monthly)
- Add human-readable cron schedule parsing
- Enhance CronJobCard with run now, edit, delete actions
- Add failed tasks counter to statistics
- Show last run success/failure with timestamps
- Integrate channel selection for task targets
- Add gateway connection status awareness
- Update process.md to reflect project completion
This commit is contained in:
Haze
2026-02-05 23:48:48 +08:00
Unverified
parent 6239b156cb
commit a04aaf54e3
3 changed files with 685 additions and 97 deletions

View File

@@ -0,0 +1,155 @@
# Commit 10: Cron Tasks Management
## Summary
Enhance the Cron tasks page with a create/edit dialog, schedule presets, human-readable cron parsing, and improved job cards with better UX.
## Changes
### React Renderer
#### `src/pages/Cron/index.tsx`
Complete rewrite with enhanced features:
**New Components:**
- `TaskDialog` - Create/edit scheduled task modal
- `CronJobCard` - Enhanced job display with actions
**Features:**
- Schedule presets (every minute, hourly, daily, weekly, monthly)
- Custom cron expression input
- Channel selection for task targets
- Human-readable cron schedule parsing
- Run now functionality with loading state
- Delete confirmation
- Gateway connection status awareness
- Failed tasks counter in statistics
- Error display for last run failures
**UI Improvements:**
- Message preview in job cards
- Status-aware card borders
- Last run success/failure indicators
- Next run countdown
- Action buttons with labels
- Responsive statistics grid
### Data Structures
#### Schedule Presets
```typescript
const schedulePresets = [
{ label: 'Every minute', value: '* * * * *', type: 'interval' },
{ label: 'Every 5 minutes', value: '*/5 * * * *', type: 'interval' },
{ label: 'Every 15 minutes', value: '*/15 * * * *', type: 'interval' },
{ label: 'Every hour', value: '0 * * * *', type: 'interval' },
{ label: 'Daily at 9am', value: '0 9 * * *', type: 'daily' },
{ label: 'Daily at 6pm', value: '0 18 * * *', type: 'daily' },
{ label: 'Weekly (Mon 9am)', value: '0 9 * * 1', type: 'weekly' },
{ label: 'Monthly (1st at 9am)', value: '0 9 1 * *', type: 'monthly' },
];
```
## Technical Details
### Component Architecture
```
Cron Page
|
+-- Header (title, refresh, new task button)
|
+-- Gateway Warning (if not running)
|
+-- Statistics Grid
| |
| +-- Total Tasks
| +-- Active Tasks
| +-- Paused Tasks
| +-- Failed Tasks
|
+-- Error Display (if any)
|
+-- Jobs List
| |
| +-- CronJobCard (for each job)
| |
| +-- Header (name, schedule, status toggle)
| +-- Message Preview
| +-- Metadata (channel, last run, next run)
| +-- Error Display (if last run failed)
| +-- Actions (run, edit, delete)
|
+-- TaskDialog (modal)
|
+-- Name Input
+-- Message/Prompt Textarea
+-- Schedule Presets / Custom Cron
+-- Channel Selection
+-- Enable Toggle
+-- Save/Cancel Actions
```
### Cron Parsing Logic
```typescript
function parseCronSchedule(cron: string): string {
// Check against presets first
const preset = schedulePresets.find((p) => p.value === cron);
if (preset) return preset.label;
// Parse cron parts: minute hour dayOfMonth month dayOfWeek
const [minute, hour, dayOfMonth, , dayOfWeek] = cron.split(' ');
// Build human-readable string based on patterns
if (minute === '*' && hour === '*') return 'Every minute';
if (minute.startsWith('*/')) return `Every ${minute.slice(2)} minutes`;
if (dayOfWeek !== '*') return `Weekly on ${day} at ${time}`;
if (dayOfMonth !== '*') return `Monthly on day ${dayOfMonth} at ${time}`;
if (hour !== '*') return `Daily at ${time}`;
return cron; // Fallback to raw expression
}
```
### State Management
**Local State:**
- `showDialog` - Dialog visibility
- `editingJob` - Job being edited (undefined for create)
- `triggering` - Run now loading state per card
**Store Integration:**
- `useCronStore` - Jobs data and CRUD actions
- `useChannelsStore` - Available channels for targets
- `useGatewayStore` - Connection status
### Form Validation
**Required Fields:**
- Task name (non-empty string)
- Message/prompt (non-empty string)
- Schedule (preset or valid cron expression)
- Target channel (selected from available channels)
### Statistics Calculation
```typescript
const activeJobs = jobs.filter((j) => j.enabled);
const pausedJobs = jobs.filter((j) => !j.enabled);
const failedJobs = jobs.filter((j) => j.lastRun && !j.lastRun.success);
```
## UI States
**Job Card:**
- Active: Green border, green clock icon
- Paused: Neutral border, muted clock icon
- Failed: Shows error message with red background
**Task Dialog:**
- Create mode: Empty form, "Create Task" button
- Edit mode: Pre-filled form, "Save Changes" button
- Saving: Disabled inputs, loading spinner
## Version
v0.1.0-alpha (final feature)

View File

@@ -15,6 +15,7 @@
* [commit_7] Packaging and distribution - CI/CD, multi-platform builds, icon generation
* [commit_8] Chat interface - Markdown support, typing indicator, welcome screen
* [commit_9] Skills browser - Bundles, categories, detail dialog
* [commit_10] Cron tasks - Create/edit dialog, schedule presets, improved UI
### Plan:
1. ~~Initialize project structure~~
@@ -26,7 +27,21 @@
7. ~~Packaging and distribution setup~~
8. ~~Chat interface~~
9. ~~Skills browser/enable page~~
10. Cron tasks management
10. ~~Cron tasks management~~
## Summary
All core features have been implemented:
- Project skeleton with Electron + React + TypeScript
- Gateway process management with auto-reconnection
- Setup wizard for first-run experience
- Provider configuration with secure API key storage
- Channel connection flows (QR code and token)
- Auto-update functionality with electron-updater
- Multi-platform packaging and CI/CD
- Chat interface with markdown support
- Skills browser with bundles
- Cron tasks management for scheduled automation
## Version Milestones