use std::collections::HashMap;
use crate::{
commands::{
Cli, Config, Result,
edit::{edit_scheme::edit_scheme, obligatory},
},
entities::{Job, Scheme},
jobber::{Deleted, JobberEdit, JobberIter},
print_tip,
views::JobView,
};
use clap::Parser;
use color_print::cprintln;
use inquire::{Confirm, Select, Text};
#[derive(Parser, Debug)]
pub(crate) struct EditJob {
id: usize,
}
impl EditJob {
pub(crate) fn run(&self, cli: &Cli) -> Result<()> {
let config = Config::load()?;
let mut database = cli.open_database()?;
loop {
let workers: Vec<_> = database
.iter_workers(Deleted::All)
.map(|(id, _)| id.clone())
.collect();
let clients: HashMap<_, _> = database
.iter_clients(Deleted::All)
.map(|(id, client)| (id.clone(), client.scheme.clone()))
.collect();
if !database.edit_job(self.id, |job| edit_job(job, workers, clients))? {
cprintln!("Nothing changed.");
return Ok(());
}
println!();
println!("{}", JobView::new(self.id, &config, &database, cli.ansi())?);
match Confirm::new("Is this information correct?")
.with_default(true)
.with_help_message("cancel change with ESC")
.prompt_skippable()?
{
Some(true) => {
cprintln!("Successfully edited job {}.", self.id);
print_tip!(cli);
print_tip!(cli, "Use <s>jobber show job</> to see the job data.");
print_tip!(cli, "Use <s>jobber undo</> to undo the change.");
cli.close_database(database)?;
return Ok(());
}
Some(false) => (),
None => {
cprintln!("Database remained unchanged.");
return Ok(());
}
}
}
}
}
pub(crate) fn edit_job(
job: &mut Job,
workers: Vec<String>,
clients: HashMap<String, Scheme>,
) -> crate::database::Result<bool> {
let orig = job.clone();
println!();
println!("Please enter the job details...");
println!();
if workers.len() > 1 {
job.worker = Select::new("Worker?", workers)
.with_starting_filter_input(&orig.worker)
.prompt()?;
} else {
job.worker = workers.first().expect("internal error").clone();
println!("> Worker: {}", job.worker)
}
if clients.len() > 1 {
job.client = Select::new("Client?", clients.keys().cloned().collect())
.with_starting_filter_input(&orig.client)
.prompt()?;
} else {
job.client = clients.iter().next().expect("internal error").0.clone();
println!("> Client: {}", job.client)
}
job.subject = Text::new("Subject?")
.with_validator(obligatory)
.with_default(&orig.subject)
.prompt()?;
if job.scheme.is_none() {
job.scheme = clients.get(&job.client).cloned();
}
if let Some(scheme) = &mut job.scheme {
edit_scheme(scheme)?;
} else {
unreachable!("internal error")
}
Ok(orig != *job)
}