diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs index b1a2b64..39a2d6c 100644 --- a/src/app_data/container_state.rs +++ b/src/app_data/container_state.rs @@ -356,6 +356,7 @@ pub type CpuTuple = (Vec<(f64, f64)>, CpuStats, State); /// Info for each container #[derive(Debug, Clone)] pub struct ContainerItem { + pub created: u64, pub cpu_stats: VecDeque, pub docker_controls: StatefulList, pub id: ContainerId, @@ -366,19 +367,27 @@ pub struct ContainerItem { pub mem_stats: VecDeque, pub name: String, pub rx: ByteStats, - pub tx: ByteStats, pub state: State, pub status: String, + pub tx: ByteStats, } impl ContainerItem { /// Create a new container item - pub fn new(id: ContainerId, status: String, image: String, state: State, name: String) -> Self { + pub fn new( + id: ContainerId, + status: String, + image: String, + state: State, + name: String, + created: u64, + ) -> Self { let mut docker_controls = StatefulList::new(DockerControls::gen_vec(state)); docker_controls.start(); let mut logs = StatefulList::new(vec![]); logs.end(); Self { + created, cpu_stats: VecDeque::with_capacity(60), docker_controls, id, @@ -389,9 +398,9 @@ impl ContainerItem { mem_stats: VecDeque::with_capacity(60), name, rx: ByteStats::default(), - tx: ByteStats::default(), state, status, + tx: ByteStats::default(), } } diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index e429d1c..18fa486 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -11,10 +11,10 @@ pub use container_state::*; /// Global app_state, stored in an Arc #[derive(Debug, Clone)] pub struct AppData { - args: CliArgs, error: Option, logs_parsed: bool, sorted_by: Option<(Header, SortedOrder)>, + pub args: CliArgs, pub containers: StatefulList, } @@ -171,19 +171,20 @@ impl AppData { output } - /// Sort the containers vec, based on a heading, either ascending or descending - pub fn sort_containers(&mut self) { - if let Some((head, ord)) = self.sorted_by.as_ref() { + /// Sort the containers vec, based on a heading, either ascending or descending, + /// If not sort set, then sort by created time + fn sort_containers(&mut self) { + if let Some((head, ord)) = self.sorted_by { match head { Header::State => match ord { - SortedOrder::Desc => self - .containers - .items - .sort_by(|a, b| a.state.order().cmp(&b.state.order())), SortedOrder::Asc => self .containers .items .sort_by(|a, b| b.state.order().cmp(&a.state.order())), + SortedOrder::Desc => self + .containers + .items + .sort_by(|a, b| a.state.order().cmp(&b.state.order())), }, Header::Status => match ord { SortedOrder::Asc => self @@ -238,6 +239,10 @@ impl AppData { SortedOrder::Desc => self.containers.items.sort_by(|a, b| b.tx.cmp(&a.tx)), }, } + } else { + self.containers + .items + .sort_by(|a, b| a.created.cmp(&b.created)) } } @@ -428,9 +433,13 @@ impl AppData { pub fn update_containers(&mut self, all_containers: &mut [ContainerSummary]) { let all_ids = self.get_all_ids(); + // Sort the containes by created, that have a constant order + all_containers.sort_by(|a, b| a.created.cmp(&b.created)); + if !all_containers.is_empty() && self.containers.state.selected().is_none() { self.containers.start(); } + let now = Self::get_systemtime(); for (index, id) in all_ids.iter().enumerate() { if !all_containers @@ -472,6 +481,8 @@ impl AppData { .map_or(String::new(), std::clone::Clone::clone); let id = ContainerId::from(id); + + let created = i.created.map_or(now, |i| u64::try_from(i).unwrap_or(now)); // If container info already in containers Vec, then just update details if let Some(item) = self.get_container_by_id(&id) { if item.name != name { @@ -496,7 +507,7 @@ impl AppData { }; // else container not known, so make new ContainerItem and push into containers Vec } else { - let container = ContainerItem::new(id, status, image, state, name); + let container = ContainerItem::new(id, status, image, state, name, created); self.containers.items.push(container); } } diff --git a/src/input_handler/mod.rs b/src/input_handler/mod.rs index 5f61d01..774ec85 100644 --- a/src/input_handler/mod.rs +++ b/src/input_handler/mod.rs @@ -121,13 +121,16 @@ impl InputHandler { self.mouse_capture = !self.mouse_capture; } - /// Sort containers based on a given header, switch asc to desc if already sorted, else always desc - fn sort(&self, header: Header) { - let mut output = Some((header, SortedOrder::Desc)); + /// Sort containers based on a given header, if headings match, and already ascending, remove sorting + fn sort(&self, selected_header: Header) { let mut locked_data = self.app_data.lock(); - if let Some((h, order)) = locked_data.get_sorted().as_ref() { - if &SortedOrder::Desc == order && h == &header { - output = Some((header, SortedOrder::Asc)); + let mut output = Some((selected_header, SortedOrder::Desc)); + if let Some((current_header, order)) = locked_data.get_sorted() { + if current_header == selected_header { + match order { + SortedOrder::Asc => output = None, + SortedOrder::Desc => output = Some((selected_header, SortedOrder::Asc)), + } } } locked_data.set_sorted(output); diff --git a/src/main.rs b/src/main.rs index 6f69c8c..5b4b42a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,7 +50,6 @@ async fn main() { let docker = Arc::new(docker); let is_running = Arc::clone(&is_running); tokio::spawn(DockerData::init( - args, docker_app_data, docker, docker_gui_state,