Skip to content

Commit 25029f4

Browse files
committed
add job log view in tui
1 parent 375f8fc commit 25029f4

19 files changed

Lines changed: 337 additions & 40 deletions

coman/src/app/ids.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
pub enum Id {
33
Toolbar,
44
WorkloadList,
5+
WorkloadLogs,
56
GlobalListener,
67
Menu,
78
InfoPopup,

coman/src/app/messages.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ pub enum CscsMsg {
3838
SelectSystem,
3939
SystemSelected(String),
4040
}
41-
41+
#[derive(Debug, PartialEq)]
42+
pub enum JobMsg {
43+
ShowLog(usize),
44+
CloseLog,
45+
}
4246
#[derive(Debug, PartialEq)]
4347
pub enum Msg {
4448
AppClose,
@@ -50,5 +54,6 @@ pub enum Msg {
5054
Error(String),
5155
Info(String),
5256
Cscs(CscsMsg),
57+
Job(JobMsg),
5358
None,
5459
}

coman/src/app/model.rs

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ use crate::{
1010
app::{
1111
ids::Id,
1212
messages::{
13-
CscsMsg, ErrorPopupMsg, InfoPopupMsg, LoginPopupMsg, MenuMsg, Msg, SystemSelectMsg,
13+
CscsMsg, ErrorPopupMsg, InfoPopupMsg, JobMsg, LoginPopupMsg, MenuMsg, Msg,
14+
SystemSelectMsg,
1415
},
1516
user_events::UserEvent,
1617
},
1718
components::{
1819
error_popup::ErrorPopup, info_popup::InfoPopup, login_popup::LoginPopup,
19-
system_select_popup::SystemSelectPopup, workload_menu::WorkloadMenu,
20+
system_select_popup::SystemSelectPopup, workload_list::WorkloadList,
21+
workload_log::WorkloadLog, workload_menu::WorkloadMenu,
2022
},
2123
cscs::{cli::cscs_login, handlers::cscs_system_set},
2224
trace_dbg,
@@ -42,6 +44,10 @@ where
4244

4345
/// Triggers async request to select current system
4446
pub select_system_tx: mpsc::Sender<()>,
47+
48+
/// Triggers watching job logs
49+
/// sending None stops watching
50+
pub job_log_tx: mpsc::Sender<Option<usize>>,
4551
}
4652

4753
impl<T> Model<T>
@@ -53,6 +59,7 @@ where
5359
bridge: TerminalBridge<T>,
5460
error_tx: mpsc::Sender<String>,
5561
select_system_tx: mpsc::Sender<()>,
62+
job_log_tx: mpsc::Sender<Option<usize>>,
5663
) -> Self {
5764
Self {
5865
app,
@@ -61,6 +68,7 @@ where
6168
terminal: bridge,
6269
error_tx,
6370
select_system_tx,
71+
job_log_tx,
6472
}
6573
}
6674

@@ -79,7 +87,11 @@ where
7987
.as_ref(),
8088
)
8189
.split(f.area());
82-
self.app.view(&Id::WorkloadList, f, chunks[0]);
90+
if self.app.mounted(&Id::WorkloadList) {
91+
self.app.view(&Id::WorkloadList, f, chunks[0]);
92+
} else if self.app.mounted(&Id::WorkloadLogs) {
93+
self.app.view(&Id::WorkloadLogs, f, chunks[0]);
94+
}
8395
self.app.view(&Id::Toolbar, f, chunks[1]);
8496

8597
if self.app.mounted(&Id::Menu) {
@@ -157,6 +169,9 @@ where
157169
fn handle_error_popup_msg(&mut self, msg: ErrorPopupMsg) -> Option<Msg> {
158170
match msg {
159171
ErrorPopupMsg::Opened(error_msg) => {
172+
if self.app.mounted(&Id::ErrorPopup) {
173+
assert!(self.app.umount(&Id::ErrorPopup).is_ok());
174+
}
160175
assert!(
161176
self.app
162177
.mount(Id::ErrorPopup, Box::new(ErrorPopup::new(error_msg)), vec![])
@@ -217,6 +232,47 @@ where
217232
}
218233
}
219234
}
235+
fn handle_job_msg(&mut self, msg: JobMsg) -> Option<Msg> {
236+
match msg {
237+
JobMsg::ShowLog(jobid) => {
238+
if self.app.mounted(&Id::WorkloadList) {
239+
assert!(self.app.umount(&Id::WorkloadList).is_ok());
240+
}
241+
if !self.app.mounted(&Id::WorkloadLogs) {
242+
assert!(
243+
self.app
244+
.mount(Id::WorkloadLogs, Box::new(WorkloadLog::new()), vec![])
245+
.is_ok()
246+
);
247+
}
248+
assert!(self.app.active(&Id::WorkloadLogs).is_ok());
249+
let job_log_tx = self.job_log_tx.clone();
250+
tokio::spawn(async move {
251+
job_log_tx.send(Some(jobid)).await.unwrap();
252+
});
253+
None
254+
}
255+
JobMsg::CloseLog => {
256+
if self.app.mounted(&Id::WorkloadLogs) {
257+
assert!(self.app.umount(&Id::WorkloadLogs).is_ok());
258+
}
259+
if !self.app.mounted(&Id::WorkloadList) {
260+
assert!(
261+
self.app
262+
.mount(Id::WorkloadList, Box::new(WorkloadList::default()), vec![])
263+
.is_ok()
264+
);
265+
}
266+
assert!(self.app.active(&Id::WorkloadList).is_ok());
267+
let job_log_tx = self.job_log_tx.clone();
268+
tokio::spawn(async move {
269+
// stopp polling for logs
270+
job_log_tx.send(None).await.unwrap();
271+
});
272+
None
273+
}
274+
}
275+
}
220276
}
221277

222278
// Let's implement Update for model
@@ -284,6 +340,7 @@ where
284340
}
285341
Msg::LoginPopup(msg) => self.handle_login_popup_msg(msg),
286342
Msg::SystemSelectPopup(msg) => self.handle_system_select_popup_msg(msg),
343+
Msg::Job(msg) => self.handle_job_msg(msg),
287344
Msg::None => None,
288345
}
289346
} else {

coman/src/app/user_events.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::cscs::api_client::{Job, System};
44
pub enum CscsEvent {
55
LoggedIn,
66
GotWorkloadData(Vec<Job>),
7+
GotJobLog(String),
78
SelectSystemList(Vec<System>),
89
}
910

coman/src/cli.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,13 @@ pub enum CscsJobCommands {
4040
#[clap(alias("ls"))]
4141
List,
4242
#[clap(alias("g"))]
43-
Get { job_id: i64 },
43+
Get {
44+
job_id: i64,
45+
},
46+
Log {
47+
job_id: i64,
48+
},
49+
4450
#[clap(alias("s"))]
4551
Submit {
4652
#[clap(short, long, help = "the path to the srun script file to use")]
@@ -59,7 +65,9 @@ pub enum CscsJobCommands {
5965
command: Option<Vec<String>>,
6066
},
6167
#[clap(alias("c"))]
62-
Cancel { job_id: i64 },
68+
Cancel {
69+
job_id: i64,
70+
},
6371
}
6472
#[derive(Subcommand, Debug)]
6573
pub enum CscsSystemCommands {

coman/src/components/error_popup.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ impl ErrorPopup {
2525
.color(Color::Red),
2626
)
2727
.title("Error", Alignment::Left)
28-
.text(vec![TextSpan::from(msg)]),
28+
.text(
29+
std::convert::Into::<String>::into(msg)
30+
.lines()
31+
.map(TextSpan::from),
32+
),
2933
}
3034
}
3135
}

coman/src/components/login_popup.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use tui_realm_stdlib::Input;
22
use tuirealm::{
33
Component, Event, Frame, MockComponent, State,
44
command::{Cmd, CmdResult, Direction, Position},
5-
event::{Key, KeyEvent, KeyModifiers},
5+
event::{Key, KeyEvent},
66
props::{
77
Alignment, AttrValue, Attribute, BorderType, Borders, Color, InputType, Layout, Props,
88
Style,

coman/src/components/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ pub(crate) mod login_popup;
55
pub(crate) mod system_select_popup;
66
pub(crate) mod toolbar;
77
pub(crate) mod workload_list;
8+
pub(crate) mod workload_log;
89
pub(crate) mod workload_menu;

coman/src/components/system_select_popup.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
use tui_realm_stdlib::List;
22
use tuirealm::{
3-
Component, Event, Frame, MockComponent, State, StateValue,
3+
Component, Event, MockComponent, State, StateValue,
44
command::{Cmd, CmdResult, Direction, Position},
5-
event::{Key, KeyEvent, KeyModifiers},
5+
event::{Key, KeyEvent},
66
props::{
7-
Alignment, AttrValue, Attribute, BorderType, Borders, Color, InputType, Layout, Props,
8-
Style, TableBuilder, TextSpan,
9-
},
10-
ratatui::{
11-
layout::{Constraint, Direction as LayoutDirection, Rect},
12-
widgets::Block,
7+
Alignment, BorderType, Borders, Color, TableBuilder, TextSpan,
138
},
149
};
1510

coman/src/components/toolbar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ impl Toolbar {
1212
pub fn new() -> Self {
1313
Self {
1414
component: Label::default()
15-
.text("q: quit, tab/shift+tab: change focus, x: menu, ?: help"),
15+
.text("q: quit, l: logs, tab/shift+tab: change focus, x: menu, ?: help"),
1616
}
1717
}
1818
}

0 commit comments

Comments
 (0)