Skip to content

Commit 4b82df9

Browse files
authored
prettify workload list and add workload details view (#35)
1 parent 366e7d4 commit 4b82df9

17 files changed

Lines changed: 291 additions & 89 deletions

File tree

coman/src/app/ids.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub enum Id {
44
Toolbar,
55
WorkloadList,
66
WorkloadLogs,
7+
WorkloadDetails,
78
GlobalListener,
89
Menu,
910
InfoPopup,

coman/src/app/messages.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use std::path::PathBuf;
22

3-
use crate::{app::user_events::UserEvent, cscs::api_client::System};
3+
use crate::{
4+
app::user_events::UserEvent,
5+
cscs::api_client::{JobDetail, System},
6+
};
47

58
#[derive(Debug, PartialEq)]
69
pub enum MenuMsg {
@@ -49,7 +52,9 @@ pub enum CscsMsg {
4952
}
5053
#[derive(Debug, PartialEq)]
5154
pub enum JobMsg {
52-
Show(usize),
55+
Log(usize),
56+
Details(JobDetail),
57+
GetDetails(usize),
5358
Switch,
5459
Close,
5560
}

coman/src/app/model.rs

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use eyre::{Context, Report};
22
use tokio::sync::mpsc;
33
use tuirealm::{
4-
Application, Update,
4+
Application, AttrValue, Attribute, Update,
55
ratatui::{
66
Frame,
77
layout::{Constraint, Direction, Layout, Rect},
@@ -21,12 +21,12 @@ use crate::{
2121
},
2222
components::{
2323
context_menu::ContextMenu, download_popup::DownloadTargetInput, error_popup::ErrorPopup, info_popup::InfoPopup,
24-
login_popup::LoginPopup, system_select_popup::SystemSelectPopup, workload_list::WorkloadList,
25-
workload_log::WorkloadLog,
24+
login_popup::LoginPopup, system_select_popup::SystemSelectPopup, workload_details::WorkloadDetails,
25+
workload_list::WorkloadList, workload_log::WorkloadLog,
2626
},
2727
cscs::{
2828
handlers::{cscs_login, cscs_system_set},
29-
ports::{JobLogAction, TreeAction},
29+
ports::{BackgroundTask, JobLogAction},
3030
},
3131
trace_dbg,
3232
util::ui::{draw_area_in_absolute, draw_area_in_absolute_fixed_height},
@@ -62,7 +62,7 @@ where
6262
pub user_event_tx: mpsc::Sender<UserEvent>,
6363

6464
/// Allows interacting with the file Api
65-
pub file_tree_tx: mpsc::Sender<TreeAction>,
65+
pub background_task_tx: mpsc::Sender<BackgroundTask>,
6666
}
6767

6868
impl<T> Model<T>
@@ -76,7 +76,7 @@ where
7676
select_system_tx: mpsc::Sender<()>,
7777
job_log_tx: mpsc::Sender<JobLogAction>,
7878
user_event_tx: mpsc::Sender<UserEvent>,
79-
file_tree_tx: mpsc::Sender<TreeAction>,
79+
background_task_tx: mpsc::Sender<BackgroundTask>,
8080
) -> Self {
8181
Self {
8282
app,
@@ -88,7 +88,7 @@ where
8888
select_system_tx,
8989
job_log_tx,
9090
user_event_tx,
91-
file_tree_tx,
91+
background_task_tx,
9292
}
9393
}
9494

@@ -101,7 +101,6 @@ where
101101
.draw(|f| {
102102
let chunks = Layout::default()
103103
.direction(Direction::Vertical)
104-
.margin(1)
105104
.constraints(
106105
[
107106
Constraint::Max(3), //Statusbar
@@ -149,11 +148,9 @@ where
149148
}
150149

151150
fn view_workloads(app: &mut Application<Id, Msg, UserEvent>, frame: &mut Frame, area: Rect) {
152-
if app.mounted(&Id::WorkloadList) {
153-
app.view(&Id::WorkloadList, frame, area);
154-
} else if app.mounted(&Id::WorkloadLogs) {
155-
app.view(&Id::WorkloadLogs, frame, area);
156-
}
151+
app.view(&Id::WorkloadList, frame, area);
152+
app.view(&Id::WorkloadLogs, frame, area);
153+
app.view(&Id::WorkloadDetails, frame, area);
157154
}
158155
fn view_files(app: &mut Application<Id, Msg, UserEvent>, frame: &mut Frame, area: Rect) {
159156
if app.mounted(&Id::FileView) {
@@ -263,9 +260,9 @@ where
263260
}
264261
DownloadPopupMsg::PathSet(remote, local) => {
265262
assert!(self.app.umount(&Id::DownloadPopup).is_ok());
266-
let file_tx = self.file_tree_tx.clone();
263+
let file_tx = self.background_task_tx.clone();
267264
tokio::spawn(async move {
268-
file_tx.send(TreeAction::Download(remote, local)).await.unwrap();
265+
file_tx.send(BackgroundTask::DownloadFile(remote, local)).await.unwrap();
269266
});
270267
None
271268
}
@@ -306,9 +303,13 @@ where
306303
}
307304
fn handle_job_msg(&mut self, msg: JobMsg) -> Option<Msg> {
308305
match msg {
309-
JobMsg::Show(jobid) => {
306+
JobMsg::Log(jobid) => {
310307
if self.app.mounted(&Id::WorkloadList) {
311-
assert!(self.app.umount(&Id::WorkloadList).is_ok());
308+
assert!(
309+
self.app
310+
.attr(&Id::WorkloadList, Attribute::Display, AttrValue::Flag(false))
311+
.is_ok()
312+
);
312313
}
313314
if !self.app.mounted(&Id::WorkloadLogs) {
314315
assert!(
@@ -324,6 +325,38 @@ where
324325
});
325326
None
326327
}
328+
JobMsg::GetDetails(jobid) => {
329+
let background_tx = self.background_task_tx.clone();
330+
let event_tx = self.user_event_tx.clone();
331+
tokio::spawn(async move {
332+
background_tx.send(BackgroundTask::GetJobDetails(jobid)).await.unwrap();
333+
event_tx
334+
.send(UserEvent::Status(StatusEvent::Info(
335+
"getting job details...".to_owned(),
336+
)))
337+
.await
338+
.unwrap();
339+
});
340+
None
341+
}
342+
JobMsg::Details(jobdetail) => {
343+
if self.app.mounted(&Id::WorkloadList) {
344+
assert!(
345+
self.app
346+
.attr(&Id::WorkloadList, Attribute::Display, AttrValue::Flag(false))
347+
.is_ok()
348+
);
349+
}
350+
if !self.app.mounted(&Id::WorkloadDetails) {
351+
assert!(
352+
self.app
353+
.mount(Id::WorkloadDetails, Box::new(WorkloadDetails::new(jobdetail)), vec![])
354+
.is_ok()
355+
);
356+
}
357+
assert!(self.app.active(&Id::WorkloadDetails).is_ok());
358+
None
359+
}
327360
JobMsg::Switch => {
328361
let job_log_tx = self.job_log_tx.clone();
329362
tokio::spawn(async move {
@@ -335,13 +368,21 @@ where
335368
if self.app.mounted(&Id::WorkloadLogs) {
336369
assert!(self.app.umount(&Id::WorkloadLogs).is_ok());
337370
}
371+
if self.app.mounted(&Id::WorkloadDetails) {
372+
assert!(self.app.umount(&Id::WorkloadDetails).is_ok());
373+
}
338374
if !self.app.mounted(&Id::WorkloadList) {
339375
assert!(
340376
self.app
341377
.mount(Id::WorkloadList, Box::new(WorkloadList::default()), vec![])
342378
.is_ok()
343379
);
344380
}
381+
assert!(
382+
self.app
383+
.attr(&Id::WorkloadList, Attribute::Display, AttrValue::Flag(true))
384+
.is_ok()
385+
);
345386
assert!(self.app.active(&Id::WorkloadList).is_ok());
346387
let job_log_tx = self.job_log_tx.clone();
347388
tokio::spawn(async move {

coman/src/app/user_events.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use crate::{
22
app::messages::View,
3-
cscs::api_client::{Job, PathEntry, System},
3+
cscs::api_client::{Job, JobDetail, PathEntry, System},
44
};
55

66
#[derive(Debug, Eq, Clone, PartialEq, PartialOrd, Ord)]
77
pub enum CscsEvent {
88
LoggedIn,
99
GotWorkloadData(Vec<Job>),
1010
GotJobLog(String),
11+
GotJobDetails(JobDetail),
1112
SelectSystemList(Vec<System>),
1213
SystemSelected(String),
1314
}

coman/src/cli.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ pub enum CscsJobCommands {
7171

7272
#[clap(alias("s"), about = "Submit a new compute job [aliases: s]")]
7373
Submit {
74+
#[clap(short, long, help = "name of the job")]
75+
name: Option<String>,
7476
#[clap(short, long, help = "the path to the srun script file to use")]
7577
script_file: Option<PathBuf>,
7678
#[clap(

coman/src/components/file_tree.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
messages::{DownloadPopupMsg, Msg},
1515
user_events::{FileEvent, UserEvent},
1616
},
17-
cscs::{api_client::PathType, ports::TreeAction},
17+
cscs::{api_client::PathType, ports::BackgroundTask},
1818
};
1919

2020
#[derive(Debug, PartialEq, PartialOrd, Ord, Eq, Clone)]
@@ -47,16 +47,21 @@ impl NodeValue for FileNode {
4747
#[derive(MockComponent)]
4848
pub struct FileTree {
4949
component: TreeView<FileNode>,
50-
file_tree_tx: mpsc::Sender<TreeAction>,
50+
file_tree_tx: mpsc::Sender<BackgroundTask>,
5151
}
5252
impl FileTree {
53-
pub fn new(file_tree_tx: mpsc::Sender<TreeAction>) -> Self {
53+
pub fn new(file_tree_tx: mpsc::Sender<BackgroundTask>) -> Self {
5454
let root_node: Node<FileNode> = Node::new("/".to_owned(), FileNode::default());
5555
let tree = Tree::new(root_node.clone());
5656

5757
// Load root node
5858
let tree_tx = file_tree_tx.clone();
59-
tokio::spawn(async move { tree_tx.send(TreeAction::List(PathBuf::from("/"))).await.unwrap() });
59+
tokio::spawn(async move {
60+
tree_tx
61+
.send(BackgroundTask::ListPaths(PathBuf::from("/")))
62+
.await
63+
.unwrap()
64+
});
6065

6166
Self {
6267
component: TreeView::default()
@@ -110,7 +115,10 @@ impl Component<Msg, UserEvent> for FileTree {
110115
// try loading children if there are none
111116
let tree_tx = self.file_tree_tx.clone();
112117
tokio::spawn(async move {
113-
tree_tx.send(TreeAction::List(PathBuf::from(current_id))).await.unwrap();
118+
tree_tx
119+
.send(BackgroundTask::ListPaths(PathBuf::from(current_id)))
120+
.await
121+
.unwrap();
114122
});
115123
CmdResult::None
116124
} else {

coman/src/components/global_listener.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use tuirealm::{
55
};
66

77
use crate::app::{
8-
messages::{MenuMsg, Msg, StatusMsg, SystemSelectMsg, View},
8+
messages::{JobMsg, MenuMsg, Msg, StatusMsg, SystemSelectMsg, View},
99
user_events::{CscsEvent, FileEvent, UserEvent},
1010
};
1111

@@ -48,6 +48,7 @@ impl Component<Msg, UserEvent> for GlobalListener {
4848
Event::User(UserEvent::Cscs(CscsEvent::SelectSystemList(systems))) => {
4949
Some(Msg::SystemSelectPopup(SystemSelectMsg::Opened(systems)))
5050
}
51+
Event::User(UserEvent::Cscs(CscsEvent::GotJobDetails(details))) => Some(Msg::Job(JobMsg::Details(details))),
5152
Event::User(UserEvent::File(FileEvent::DownloadSuccessful)) => {
5253
Some(Msg::Status(StatusMsg::Info("File successfully downloaded".to_owned())))
5354
}

coman/src/components/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ pub(crate) mod login_popup;
88
pub(crate) mod status_bar;
99
pub(crate) mod system_select_popup;
1010
pub(crate) mod toolbar;
11+
pub(crate) mod workload_details;
1112
pub(crate) mod workload_list;
1213
pub(crate) mod workload_log;

coman/src/components/status_bar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl MockComponent for StatusBar {
7272
.border_style(borders.style())
7373
.border_type(borders.modifiers);
7474
let layout = Layout::default()
75-
.constraints(&[Constraint::Percentage(30), Constraint::Percentage(70)])
75+
.constraints(&[Constraint::Min(34), Constraint::Fill(1)])
7676
.direction(Direction::Horizontal)
7777
.margin(1);
7878
frame.render_widget(div, area);

0 commit comments

Comments
 (0)