feat: default order of created time, reset sorted, closes #18

This commit is contained in:
Jack Wills
2022-12-04 21:42:54 +00:00
parent c93870e5fb
commit cf14ba4989
4 changed files with 41 additions and 19 deletions
+12 -3
View File
@@ -356,6 +356,7 @@ pub type CpuTuple = (Vec<(f64, f64)>, CpuStats, State);
/// Info for each container /// Info for each container
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ContainerItem { pub struct ContainerItem {
pub created: u64,
pub cpu_stats: VecDeque<CpuStats>, pub cpu_stats: VecDeque<CpuStats>,
pub docker_controls: StatefulList<DockerControls>, pub docker_controls: StatefulList<DockerControls>,
pub id: ContainerId, pub id: ContainerId,
@@ -366,19 +367,27 @@ pub struct ContainerItem {
pub mem_stats: VecDeque<ByteStats>, pub mem_stats: VecDeque<ByteStats>,
pub name: String, pub name: String,
pub rx: ByteStats, pub rx: ByteStats,
pub tx: ByteStats,
pub state: State, pub state: State,
pub status: String, pub status: String,
pub tx: ByteStats,
} }
impl ContainerItem { impl ContainerItem {
/// Create a new container item /// 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)); let mut docker_controls = StatefulList::new(DockerControls::gen_vec(state));
docker_controls.start(); docker_controls.start();
let mut logs = StatefulList::new(vec![]); let mut logs = StatefulList::new(vec![]);
logs.end(); logs.end();
Self { Self {
created,
cpu_stats: VecDeque::with_capacity(60), cpu_stats: VecDeque::with_capacity(60),
docker_controls, docker_controls,
id, id,
@@ -389,9 +398,9 @@ impl ContainerItem {
mem_stats: VecDeque::with_capacity(60), mem_stats: VecDeque::with_capacity(60),
name, name,
rx: ByteStats::default(), rx: ByteStats::default(),
tx: ByteStats::default(),
state, state,
status, status,
tx: ByteStats::default(),
} }
} }
+20 -9
View File
@@ -11,10 +11,10 @@ pub use container_state::*;
/// Global app_state, stored in an Arc<Mutex> /// Global app_state, stored in an Arc<Mutex>
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct AppData { pub struct AppData {
args: CliArgs,
error: Option<AppError>, error: Option<AppError>,
logs_parsed: bool, logs_parsed: bool,
sorted_by: Option<(Header, SortedOrder)>, sorted_by: Option<(Header, SortedOrder)>,
pub args: CliArgs,
pub containers: StatefulList<ContainerItem>, pub containers: StatefulList<ContainerItem>,
} }
@@ -171,19 +171,20 @@ impl AppData {
output output
} }
/// Sort the containers vec, based on a heading, either ascending or descending /// Sort the containers vec, based on a heading, either ascending or descending,
pub fn sort_containers(&mut self) { /// If not sort set, then sort by created time
if let Some((head, ord)) = self.sorted_by.as_ref() { fn sort_containers(&mut self) {
if let Some((head, ord)) = self.sorted_by {
match head { match head {
Header::State => match ord { Header::State => match ord {
SortedOrder::Desc => self
.containers
.items
.sort_by(|a, b| a.state.order().cmp(&b.state.order())),
SortedOrder::Asc => self SortedOrder::Asc => self
.containers .containers
.items .items
.sort_by(|a, b| b.state.order().cmp(&a.state.order())), .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 { Header::Status => match ord {
SortedOrder::Asc => self SortedOrder::Asc => self
@@ -238,6 +239,10 @@ impl AppData {
SortedOrder::Desc => self.containers.items.sort_by(|a, b| b.tx.cmp(&a.tx)), 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]) { pub fn update_containers(&mut self, all_containers: &mut [ContainerSummary]) {
let all_ids = self.get_all_ids(); 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() { if !all_containers.is_empty() && self.containers.state.selected().is_none() {
self.containers.start(); self.containers.start();
} }
let now = Self::get_systemtime();
for (index, id) in all_ids.iter().enumerate() { for (index, id) in all_ids.iter().enumerate() {
if !all_containers if !all_containers
@@ -472,6 +481,8 @@ impl AppData {
.map_or(String::new(), std::clone::Clone::clone); .map_or(String::new(), std::clone::Clone::clone);
let id = ContainerId::from(id); 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 container info already in containers Vec, then just update details
if let Some(item) = self.get_container_by_id(&id) { if let Some(item) = self.get_container_by_id(&id) {
if item.name != name { if item.name != name {
@@ -496,7 +507,7 @@ impl AppData {
}; };
// else container not known, so make new ContainerItem and push into containers Vec // else container not known, so make new ContainerItem and push into containers Vec
} else { } 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); self.containers.items.push(container);
} }
} }
+9 -6
View File
@@ -121,13 +121,16 @@ impl InputHandler {
self.mouse_capture = !self.mouse_capture; self.mouse_capture = !self.mouse_capture;
} }
/// Sort containers based on a given header, switch asc to desc if already sorted, else always desc /// Sort containers based on a given header, if headings match, and already ascending, remove sorting
fn sort(&self, header: Header) { fn sort(&self, selected_header: Header) {
let mut output = Some((header, SortedOrder::Desc));
let mut locked_data = self.app_data.lock(); let mut locked_data = self.app_data.lock();
if let Some((h, order)) = locked_data.get_sorted().as_ref() { let mut output = Some((selected_header, SortedOrder::Desc));
if &SortedOrder::Desc == order && h == &header { if let Some((current_header, order)) = locked_data.get_sorted() {
output = Some((header, SortedOrder::Asc)); if current_header == selected_header {
match order {
SortedOrder::Asc => output = None,
SortedOrder::Desc => output = Some((selected_header, SortedOrder::Asc)),
}
} }
} }
locked_data.set_sorted(output); locked_data.set_sorted(output);
-1
View File
@@ -50,7 +50,6 @@ async fn main() {
let docker = Arc::new(docker); let docker = Arc::new(docker);
let is_running = Arc::clone(&is_running); let is_running = Arc::clone(&is_running);
tokio::spawn(DockerData::init( tokio::spawn(DockerData::init(
args,
docker_app_data, docker_app_data,
docker, docker,
docker_gui_state, docker_gui_state,