mod link;
mod panes;
mod replies;
use super::*;
impl App {
#[must_use]
pub fn new(palette: Palette, control: Control, home: String, now: Instant) -> Self {
Self {
flock: BTreeMap::new(),
selected: None,
filter: TextBox::new(),
mode: InputMode::Normal,
next_write_ticket: 0,
sheep_dogs_ask: 0,
link: Link::Live,
notice: None,
palette,
control,
home,
remote_host: None,
now,
froze_at: None,
frozen_for: Duration::ZERO,
host: None,
host_unsupported: false,
feed: crate::lookout::tail::Tail::default(),
log_size: None,
lambs: None,
action: None,
body: Body::FlockTable,
config_target: None,
config_for: None,
dog_target: None,
dog_opening: 0,
closing: false,
config_read_in_flight: false,
close_dialog: None,
held: None,
style: (StyleLevel::Full, StyleSource::Default),
cpu_history: HashMap::new(),
flock_cpu: VecDeque::new(),
rss_history: HashMap::new(),
cpu_last: HashMap::new(),
grouping: Grouping::Flat,
collapsed_folds: HashSet::new(),
keymap_open: false,
modals: modal::Modals::default(),
focus: None,
focus_ask: None,
catalogue: Vec::new(),
dog_job: DogJob::Idle,
long_actions: Default::default(),
dog_quit: None,
hint: None,
dog_delete: None,
pane_action: None,
next_modal_tag: 0,
}
}
pub fn update(&mut self, msg: Msg) -> Effect {
match msg {
Msg::Snapshot { rows, at } => self.on_flock_snapshot(rows, at),
Msg::Event(event) => self.on_event(event),
Msg::BusLagged { count } => self.on_bus_lagged(count),
Msg::Retrying { attempt } => self.on_retrying(attempt),
Msg::Relinked => self.on_relinked(),
Msg::Frozen { at_local, why } => self.on_frozen(at_local, why),
Msg::Tick { now } => self.on_tick(now),
Msg::Resize => Effect::None,
Msg::Key(key) => self.on_key(key),
Msg::Paste(text) => self.on_paste(text.as_str()),
Msg::Host { sample } => self.on_host(sample),
Msg::Hint { line } => self.on_hint(line),
Msg::LogSize { id, total_bytes } => self.on_log_size(id, total_bytes),
Msg::Bleats { tail } => self.on_bleats(tail),
Msg::Replied { sent, result } => self.on_replied(sent, result),
Msg::Unsent { sent } => self.on_unsent(sent),
Msg::BatchSent { unsent } => self.on_batch_sent(unsent),
Msg::Settings { result } => self.on_settings(result),
Msg::SettingWritten {
edit,
ticket,
result,
} => self.on_setting_written(edit, ticket, result),
Msg::DogPane {
name,
adopted_path,
env_keys,
result,
} => self.on_dog_pane_answer(name, adopted_path, env_keys, result),
Msg::DogDeclaresPane {
name,
opening,
declared,
} => self.on_dog_declares_pane(&name, opening, declared),
Msg::SheepDogNames { sheep, ask, dogs } => {
self.on_sheep_dog_names_answer(sheep, ask, dogs)
}
Msg::SheepDog { sheep, entry } => self.on_sheep_dog_answer(&sheep, entry),
Msg::SheepDogSections { sheep, entries } => self.on_sheep_dog_sections(&sheep, entries),
Msg::DogWritten {
edit,
ticket,
result,
} => self.on_dog_written(edit, ticket, result),
Msg::DogEnvWritten {
name,
ticket,
then,
result,
} => self.on_dog_env_written(&name, ticket, then, result),
Msg::DogTuneWritten {
tune,
ticket,
result,
} => self.on_dog_tune_written(tune, ticket, result),
Msg::Secrets {
environment,
result,
} => self.on_secrets(environment, result),
Msg::Revealed {
key,
environment,
value,
} => self.on_revealed_answer(key, environment, value),
Msg::SecretWritten { result } => self.on_secret_written(result),
Msg::Catalogue { result } => self.on_catalogue(result),
Msg::DogStep { name, step } => self.on_dog_step(&name, step),
Msg::DogGrant {
name,
prompt,
reply,
} => self.on_dog_grant(&name, prompt, reply),
Msg::DogJobDone { name, ok, output } => self.on_dog_job_done(&name, ok, output),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::lookout::app::testing::*;
#[test]
fn every_action_key_refuses_while_the_gate_is_closed() {
for verb in [ActionVerb::Stop, ActionVerb::Restart, ActionVerb::Reload] {
let (mut app, _t0) = started();
app.update(Msg::Key(KeyPress::Action(verb)));
assert!(
app.action().is_none(),
"{verb:?} armed behind a closed gate"
);
assert_eq!(
app.notice().map(ToString::to_string).as_deref(),
Some("read-only: from --read-only or lookout.allow_control"),
"{verb:?}"
);
}
}
#[test]
fn the_next_keypress_clears_the_notice() {
let (mut app, _) = started();
app.update(Msg::Key(KeyPress::Action(ActionVerb::Stop)));
assert!(app.notice().is_some());
app.update(Msg::Key(KeyPress::SelectDown));
assert!(app.notice().is_none());
}
}