Skip to content

Add Schedules section to the Settings UI (#303)#304

Open
germanescobar wants to merge 3 commits into
mainfrom
issue-303
Open

Add Schedules section to the Settings UI (#303)#304
germanescobar wants to merge 3 commits into
mainfrom
issue-303

Conversation

@germanescobar

Copy link
Copy Markdown
Owner

Summary

Adds a new Schedules entry to the in-app Settings page so the user can manage scheduled sessions on the active project without leaving the app.

  • New client/src/components/schedules-section.tsx — self-contained component mounted from SECTIONS in Settings.tsx (data-testid="settings-nav-schedules").
  • New schedule API helpers in client/src/api.ts (thin client over the existing REST surface in server/routes/schedules.ts; no server changes).
  • SettingsPage now accepts an optional projectId and onOpenSession so the section is project-scoped and can deep-link from a run to its session.

What works end-to-end

  1. List every schedule (including disabled) — worktree, prompt preview, trigger type (cron / runAt), next/last run, enabled state, source, last error.
  2. Create via a form mirroring the CLI: worktree (from project), prompt, and either one-shot ISO timestamp or cron + timezone. Server validation errors surface inline. createdBy: "ui".
  3. Toggle enabled/disabled with a Switch.
  4. Delete with an AlertDialog confirmation (data-testid="schedule-delete-confirm").
  5. View runs in a drawer; each run's sessionId is a button that switches the main view to that session (same path the transcript's controller:// links take).

Non-goals (deferred per the issue)

  • Editing an existing schedule's trigger (the server has no PUT route).
  • A cron helper UI (raw cron + timezone select is enough).

Validation

  • client/src/components/__tests__/schedules-section.test.tsx — 16 new tests covering list rendering (cron + one-shot rows, disabled badge, last run, last error, all action controls), the create form (worktree select, prompt, trigger toggle, both one-shot and cron fields, empty-worktree state, validation errors), the delete confirmation wiring, and the enable/disable switch.
  • Existing tests still pass (settings-responsive.test.tsx, agents-section.test.tsx, etc.). The only failing test in the suite is the pre-existing pty-manager.test.ts failure, unrelated to this change.
  • vite build succeeds.

Issue

Closes #303.

Wires a new 'Schedules' entry into the Settings page so the user
can manage the active project's scheduled sessions without leaving
the app. The component is a thin client over the existing REST
surface in server/routes/schedules.ts (the CLI is still the
source of truth; no server changes):

  * List every schedule (including disabled) with worktree, prompt
    preview, trigger type, next/last run, enabled state, source,
    and last error inline.
  * Create via a form that mirrors the CLI: worktree (from the
    project's worktrees), prompt, and either a one-shot ISO
    timestamp or a cron expression + timezone. Server-side
    validation errors (bad cron / timezone) are surfaced inline.
    'createdBy' defaults to 'ui'.
  * Toggle enabled/disabled with a Switch.
  * Delete with an AlertDialog confirmation.
  * View runs for a schedule in a drawer; each run with a
    'sessionId' is a button that switches the main view to that
    session (mirrors the 'controller://' deep-link path the
    transcript already uses).

Editing an existing schedule is intentionally not exposed — the
server has no PUT route for it (non-goal). The form resets on
close; the section refreshes after every mutation.

Plumbing: 'SettingsPage' now accepts an optional 'projectId'
and 'onOpenSession' prop so the section can be project-scoped
and so runs can deep-link to a session. Both are optional so
the page still renders without an active project.

A regression test in
'client/src/components/__tests__/schedules-section.test.tsx'
covers list rendering (cron and one-shot rows, disabled badge,
last run, last error, action controls), the create form (worktree
select, prompt, trigger toggle, both one-shot and cron fields,
empty-worktree state, validation errors), the delete
confirmation flow (data-testid contract + wiring to
'deleteSchedule'), and the enable/disable switch.
Review feedback on #303: instead of scoping the Schedules section
to the active project, list every project's schedules in one view
so the user can see everything that's about to fire without
project-hopping.

The server still has no cross-project '/api/schedules' endpoint
(the CLI is the source of truth for the data model, per the
issue's non-goals). The section fans out client-side: list
projects, then list each project's schedules, then merge. Each
row carries its projectId plus a denormalised projectName so
the action handlers (toggle, delete, runs) don't need a
separate lookup.

The create form now picks a project first and a worktree second
(worktrees are loaded on demand and cached per project). The
delete confirm dialog names the project so the user is sure
which schedule they're removing.

Regression test: 18 cases in schedules-section.test.tsx now
cover the project badge per row, the project + worktree
selectors, the loading state for worktrees, the empty-projects
state, and the cross-project delete wiring (the confirm action
must call deleteSchedule with the row's projectId, not the
section's). All 632 tests in the suite pass (the one
pre-existing pty-manager failure is unrelated).
Without this, calling 'npm run dev' from a clean shell (no exported
VITE_API_PORT) would have the dev:server script fall back to the
default 3102, while the Vite client reads .env.local via its own
loadEnv and proxies to whatever port is in there (e.g. 3129 for
this worktree). The two would land on different ports, and every
request would 404 — which is exactly the state this worktree was
in before the fix.

The loader is intentionally minimal (KEY=value with optional
quotes, no expansion): we only need the port keys, and pulling in
dotenv for three lines is overkill. Values already set in the
parent shell win, so a script that exports VITE_API_PORT
explicitly is not clobbered.

Discovered while debugging the empty-projects / /api/shortcuts 404
state in the dev tooling on issue #303.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Schedules section to the Settings UI

1 participant