ironflow_cli/commands/
schedule.rs1use anyhow::Result;
4use clap::{Args, Subcommand};
5use comfy_table::{ContentArrangement, Table};
6use ironflow_sdk::IronflowClient;
7use ironflow_sdk::types::{CreateScheduleRequest, ScheduleResponse};
8use uuid::Uuid;
9
10use crate::confirm::confirm;
11use crate::output;
12
13#[derive(Debug, Args)]
15pub struct ScheduleArgs {
16 #[command(subcommand)]
18 pub command: ScheduleCommands,
19}
20
21#[derive(Debug, Subcommand)]
23pub enum ScheduleCommands {
24 List,
26 Create {
28 workflow: String,
30 cron: String,
32 #[arg(long, default_value = "{}")]
34 inputs: String,
35 },
36 Pause {
38 id: Uuid,
40 },
41 Resume {
43 id: Uuid,
45 },
46 Delete {
48 id: Uuid,
50 #[arg(long)]
52 yes: bool,
53 },
54 Trigger {
56 id: Uuid,
58 },
59}
60
61fn schedules_table(schedules: &[ScheduleResponse]) -> Table {
62 let mut table = Table::new();
63 table.set_content_arrangement(ContentArrangement::Dynamic);
64 table.set_header(vec![
65 "ID",
66 "WORKFLOW",
67 "CRON",
68 "SOURCE",
69 "ENABLED",
70 "NEXT TRIGGER",
71 ]);
72 for s in schedules {
73 let source = format!("{:?}", s.source).to_lowercase();
74 table.add_row(vec![
75 s.id.to_string(),
76 s.workflow_name.clone(),
77 s.cron_expression.clone(),
78 source.to_string(),
79 if s.disabled_at.is_none() {
80 "active".to_string()
81 } else {
82 "paused".to_string()
83 },
84 s.next_trigger_at
85 .as_ref()
86 .map(|d| d.to_string())
87 .unwrap_or_else(|| "-".to_string()),
88 ]);
89 }
90 table
91}
92
93pub async fn execute(client: &IronflowClient, args: &ScheduleArgs, json_mode: bool) -> Result<()> {
100 match &args.command {
101 ScheduleCommands::List => {
102 let response = client.list_schedules().await?;
103 if json_mode {
104 output::print_json(&response)?;
105 } else {
106 println!("{}", schedules_table(&response.data));
107 }
108 Ok(())
109 }
110 ScheduleCommands::Create {
111 workflow,
112 cron,
113 inputs,
114 } => {
115 let parsed_inputs: serde_json::Value =
116 serde_json::from_str(inputs).map_err(|e| anyhow::anyhow!("invalid JSON: {e}"))?;
117 let response = client
118 .create_schedule(&CreateScheduleRequest {
119 workflow_name: workflow.clone(),
120 cron_expression: cron.clone(),
121 inputs: Some(parsed_inputs),
122 })
123 .await?;
124 if json_mode {
125 output::print_json(&response)?;
126 } else {
127 println!("Schedule {} created", response.data.id);
128 }
129 Ok(())
130 }
131 ScheduleCommands::Pause { id } => {
132 let response = client.pause_schedule(*id).await?;
133 if json_mode {
134 output::print_json(&response)?;
135 } else {
136 println!("Schedule {} paused", response.data.id);
137 }
138 Ok(())
139 }
140 ScheduleCommands::Resume { id } => {
141 let response = client.resume_schedule(*id).await?;
142 if json_mode {
143 output::print_json(&response)?;
144 } else {
145 println!("Schedule {} resumed", response.data.id);
146 }
147 Ok(())
148 }
149 ScheduleCommands::Delete { id, yes } => {
150 let prompt = format!("Delete schedule {id}?");
151 confirm(&prompt, *yes)?;
152 client.delete_schedule(*id).await?;
153 if json_mode {
154 output::print_json(&serde_json::json!({"deleted": id.to_string()}))?;
155 } else {
156 println!("Schedule {id} deleted");
157 }
158 Ok(())
159 }
160 ScheduleCommands::Trigger { id } => {
161 let response = client.trigger_schedule(*id).await?;
162 if json_mode {
163 output::print_json(&response)?;
164 } else {
165 println!("Schedule {} triggered", response.data.id);
166 }
167 Ok(())
168 }
169 }
170}