Skip to content

[Schedules 5/8] Add TypeScript types, API client, and sidebar navigation #21

@sre-helmcode

Description

@sre-helmcode

Implementation Order: 5 of 8 (frontend starts here, parallel with backend)

Can start in parallel with: backend issues #29-#32 (types can be defined from the API spec)
Feature: Schedules — Recurring automated tasks for AI agent teams

Summary

Add the TypeScript types, API client methods, and sidebar navigation entry for the Schedules feature.

Types (src/types/index.ts)

export interface Schedule {
  id: string;
  name: string;
  team_id: string;
  team_name?: string; // enriched by API
  prompt: string;
  cron_expression: string;
  timezone: string;
  enabled: boolean;
  last_run_at: string | null;
  next_run_at: string | null;
  status: 'idle' | 'running' | 'error';
  created_at: string;
  updated_at: string;
}

export interface ScheduleRun {
  id: string;
  schedule_id: string;
  team_deployment_id: string;
  started_at: string;
  finished_at: string | null;
  status: 'running' | 'success' | 'failed' | 'timeout';
  error: string;
}

export interface CreateScheduleRequest {
  name: string;
  team_id: string;
  prompt: string;
  cron_expression: string;
  timezone: string;
  enabled: boolean;
}

export interface UpdateScheduleRequest {
  name?: string;
  prompt?: string;
  cron_expression?: string;
  timezone?: string;
  enabled?: boolean;
}

API Client (src/services/api.ts)

export const schedulesApi = {
  list: () => request<Schedule[]>('/api/schedules'),
  get: (id: string) => request<Schedule>(`/api/schedules/${id}`),
  create: (data: CreateScheduleRequest) => request<Schedule>('/api/schedules', { method: 'POST', body: JSON.stringify(data) }),
  update: (id: string, data: UpdateScheduleRequest) => request<Schedule>(`/api/schedules/${id}`, { method: 'PUT', body: JSON.stringify(data) }),
  delete: (id: string) => request<void>(`/api/schedules/${id}`, { method: 'DELETE' }),
  toggle: (id: string) => request<Schedule>(`/api/schedules/${id}/toggle`, { method: 'PATCH' }),
  runs: (id: string) => request<ScheduleRun[]>(`/api/schedules/${id}/runs`),
  getRun: (id: string, runId: string) => request<ScheduleRun>(`/api/schedules/${id}/runs/${runId}`),
};

Sidebar (src/components/Layout.tsx)

Add "Schedules" nav item with clock icon between "Teams" and "Variables":

{
  to: '/schedules',
  label: 'Schedules',
  end: false,
  icon: (
    <svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
      <path strokeLinecap="round" strokeLinejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
    </svg>
  ),
}

Router (src/App.tsx)

Add routes:

  • /schedules → SchedulesListPage
  • /schedules/new → ScheduleBuilderPage
  • /schedules/:id → ScheduleDetailPage

Acceptance Criteria

  • All TypeScript interfaces added to types/index.ts
  • schedulesApi with all methods in api.ts
  • "Schedules" nav item in sidebar with clock icon
  • Routes registered in App.tsx (pages can be placeholder components initially)
  • Mock data added to test/mocks.ts
  • Unit tests for API client methods

Metadata

Metadata

Assignees

Labels

featureNew feature or request

Type

No type

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions