use crate::settings_ui::SettingsUI;
use par_term_config::automation::RestartPolicy;
use par_term_config::scripting::ScriptConfig;
pub(super) fn show_script_edit_form(
ui: &mut egui::Ui,
settings: &mut SettingsUI,
changes_this_frame: &mut bool,
edit_index: Option<usize>,
) {
ui.indent("script_edit_form", |ui| {
ui.horizontal(|ui| {
ui.label("Name:");
ui.text_edit_singleline(&mut settings.temp_script_name);
});
ui.horizontal(|ui| {
ui.label("Script path:");
ui.text_edit_singleline(&mut settings.temp_script_path);
if ui.button("Browse...").clicked()
&& let Some(path) = settings.pick_file_path("Select script file")
{
settings.temp_script_path = path;
}
});
ui.horizontal(|ui| {
ui.label("Arguments:");
ui.text_edit_singleline(&mut settings.temp_script_args);
});
ui.horizontal(|ui| {
ui.label("Subscriptions:");
ui.text_edit_singleline(&mut settings.temp_script_subscriptions)
.on_hover_text(
"Comma-separated event types (e.g., bell_rang, cwd_changed). Empty = all events.",
);
});
ui.checkbox(&mut settings.temp_script_enabled, "Enabled")
.on_hover_text("Whether this script is active");
ui.checkbox(
&mut settings.temp_script_auto_start,
"Auto-start with terminal",
)
.on_hover_text("Start this script automatically when a new tab is opened");
ui.horizontal(|ui| {
ui.label("Restart policy:");
egui::ComboBox::from_id_salt(if edit_index.is_some() {
"script_restart_policy_edit"
} else {
"script_restart_policy_new"
})
.selected_text(settings.temp_script_restart_policy.display_name())
.show_ui(ui, |ui| {
for &policy in RestartPolicy::all() {
ui.selectable_value(
&mut settings.temp_script_restart_policy,
policy,
policy.display_name(),
);
}
});
});
if settings.temp_script_restart_policy != RestartPolicy::Never {
ui.horizontal(|ui| {
ui.label("Restart delay (ms):");
ui.add(
egui::DragValue::new(&mut settings.temp_script_restart_delay_ms)
.range(0..=60000)
.speed(100.0),
);
});
}
ui.add_space(4.0);
show_permissions_section(ui, settings);
ui.add_space(4.0);
show_save_cancel(ui, settings, changes_this_frame, edit_index);
});
}
fn show_permissions_section(ui: &mut egui::Ui, settings: &mut SettingsUI) {
ui.label(egui::RichText::new("Permissions").strong().small());
ui.indent("script_permissions", |ui| {
ui.checkbox(
&mut settings.temp_script_allow_write_text,
"Allow WriteText",
)
.on_hover_text(
"Allow this script to inject text into the active PTY. \
VT/ANSI escape sequences are stripped before writing.",
);
if settings.temp_script_allow_write_text {
ui.indent("write_text_rate", |ui| {
ui.horizontal(|ui| {
ui.label("Rate limit (writes/sec, 0 = default 10/s):");
ui.add(
egui::DragValue::new(&mut settings.temp_script_write_text_rate_limit)
.range(0..=100)
.speed(1.0),
);
});
});
}
ui.checkbox(
&mut settings.temp_script_allow_run_command,
"Allow RunCommand",
)
.on_hover_text(
"Allow this script to spawn external processes. \
Commands are checked against the denylist and tokenised without shell invocation.",
);
if settings.temp_script_allow_run_command {
ui.indent("run_command_rate", |ui| {
ui.horizontal(|ui| {
ui.label("Rate limit (runs/sec, 0 = default 1/s):");
ui.add(
egui::DragValue::new(&mut settings.temp_script_run_command_rate_limit)
.range(0..=10)
.speed(1.0),
);
});
});
}
ui.checkbox(
&mut settings.temp_script_allow_change_config,
"Allow ChangeConfig",
)
.on_hover_text(
"Allow this script to modify runtime configuration values. \
Only allowlisted keys (font_size, window_opacity, etc.) may be changed.",
);
});
}
fn show_save_cancel(
ui: &mut egui::Ui,
settings: &mut SettingsUI,
changes_this_frame: &mut bool,
edit_index: Option<usize>,
) {
ui.horizontal(|ui| {
let can_save = !settings.temp_script_name.trim().is_empty()
&& !settings.temp_script_path.trim().is_empty();
if ui
.add_enabled(can_save, egui::Button::new("Save"))
.clicked()
{
let args: Vec<String> = settings
.temp_script_args
.split_whitespace()
.map(|s| s.to_string())
.collect();
let subscriptions: Vec<String> = settings
.temp_script_subscriptions
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect();
let new_script = ScriptConfig {
name: settings.temp_script_name.trim().to_string(),
enabled: settings.temp_script_enabled,
script_path: settings.temp_script_path.trim().to_string(),
args,
auto_start: settings.temp_script_auto_start,
restart_policy: settings.temp_script_restart_policy,
restart_delay_ms: settings.temp_script_restart_delay_ms,
subscriptions,
env_vars: if let Some(i) = edit_index {
settings.config.scripts[i].env_vars.clone()
} else {
std::collections::HashMap::new()
},
allow_write_text: settings.temp_script_allow_write_text,
allow_run_command: settings.temp_script_allow_run_command,
allow_change_config: settings.temp_script_allow_change_config,
write_text_rate_limit: settings.temp_script_write_text_rate_limit,
run_command_rate_limit: settings.temp_script_run_command_rate_limit,
};
if let Some(i) = edit_index {
settings.config.scripts[i] = new_script;
} else {
settings.config.scripts.push(new_script);
}
settings.has_changes = true;
*changes_this_frame = true;
settings.editing_script_index = None;
settings.adding_new_script = false;
}
if ui.button("Cancel").clicked() {
settings.editing_script_index = None;
settings.adding_new_script = false;
}
});
}