Skip to content

Commit

Permalink
webapp: add model for a list of evaluations
Browse files Browse the repository at this point in the history
  • Loading branch information
pnmadelaine committed Oct 18, 2023
1 parent a4a78a6 commit ba65e91
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 67 deletions.
90 changes: 23 additions & 67 deletions typhon-webapp/src/pages/jobset.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::perform_request;
use crate::view_error;
use crate::widgets::timestamp;
use crate::widgets::evaluation_list;

use seed::{prelude::*, *};
use typhon_types::*;
Expand All @@ -9,7 +9,7 @@ struct_urls!();

pub struct Model {
error: Option<responses::ResponseError>,
evaluations: Vec<(i64, timestamp::Model)>,
evaluation_list: evaluation_list::Model,
handle: handles::Jobset,
info: Option<responses::JobsetInfo>,
base_url: Url,
Expand All @@ -20,21 +20,24 @@ pub enum Msg {
Error(responses::ResponseError),
ErrorIgnored,
Evaluate(bool),
MsgEvaluationList(evaluation_list::Msg),
Event(Event),
FetchEvaluations,
FetchInfo,
GetEvaluations(Vec<(handles::Evaluation, i64)>),
GetInfo(responses::JobsetInfo),
Noop,
TimestampMsg(i64, timestamp::Msg),
}

pub fn init(base_url: Url, orders: &mut impl Orders<Msg>, handle: handles::Jobset) -> Model {
orders.send_msg(Msg::FetchEvaluations);
orders.send_msg(Msg::FetchInfo);
Model {
error: None,
evaluations: Vec::new(),
evaluation_list: evaluation_list::init(
&base_url,
&mut orders.proxy(Msg::MsgEvaluationList),
Some(handle.project.name.clone()),
Some(handle.name.clone()),
1,
),
handle: handle.clone(),
info: None,
base_url,
Expand All @@ -59,23 +62,19 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
Msg::Error,
);
}
Msg::Event(_) => {
orders.send_msg(Msg::FetchEvaluations);
orders.send_msg(Msg::FetchInfo);
Msg::MsgEvaluationList(msg) => {
evaluation_list::update(
msg,
&mut model.evaluation_list,
&mut orders.proxy(Msg::MsgEvaluationList),
);
}
Msg::FetchEvaluations => {
let handle = model.handle.clone();
let req = requests::Request::ListEvaluations(requests::EvaluationSearch {
project_name: Some(handle.project.name),
jobset_name: Some(handle.name),
offset: 0,
limit: 10,
});
perform_request!(
orders,
req,
responses::Response::ListEvaluations(evaluations) => Msg::GetEvaluations(evaluations),
Msg::Error,
Msg::Event(event) => {
orders.send_msg(Msg::FetchInfo);
evaluation_list::update(
evaluation_list::Msg::Event(event),
&mut model.evaluation_list,
&mut orders.proxy(Msg::MsgEvaluationList),
);
}
Msg::FetchInfo => {
Expand All @@ -88,39 +87,10 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
Msg::Error,
);
}
Msg::GetEvaluations(evaluations) => {
model.evaluations = evaluations
.iter()
.map(|(handle, time)| {
let num = handle.num.clone();
(
num.clone(),
timestamp::init(
&mut orders.proxy(move |msg| Msg::TimestampMsg(num, msg)),
time,
),
)
})
.collect();
}
Msg::GetInfo(info) => {
model.info = Some(info);
}
Msg::Noop => (),
Msg::TimestampMsg(id, msg) => {
model
.evaluations
.iter_mut()
.find(|(id1, _)| *id1 == id)
.map(|(_, ref mut m)| {
let id = id.clone();
timestamp::update(
msg,
m,
&mut orders.proxy(move |msg| Msg::TimestampMsg(id, msg)),
)
});
}
}
}

Expand All @@ -144,21 +114,7 @@ fn view_jobset(model: &Model) -> Node<Msg> {
Some(info) => div![div![
format!("Flake: {}", info.url),
h3!["Evaluations"],
ul![model.evaluations.iter().map(|(num, time)| {
let urls = crate::Urls::new(&model.base_url);
li![a![
timestamp::view(time).map_msg({
let num = num.clone();
move |msg| Msg::TimestampMsg(num, msg)
}),
attrs! { At::Href => urls.evaluation(
&handles::Evaluation{
jobset: model.handle.clone(),
num: *num,
}
)},
]]
}),]
evaluation_list::view(&model.evaluation_list).map_msg(Msg::MsgEvaluationList),
]],
},
]
Expand Down
142 changes: 142 additions & 0 deletions typhon-webapp/src/widgets/evaluation_list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
use crate::perform_request;
use crate::view_error;
use crate::widgets::timestamp;

use seed::{prelude::*, *};
use typhon_types::*;

pub struct Model {
base_url: Url,
error: Option<responses::ResponseError>,
evaluations: Vec<(handles::Evaluation, timestamp::Model)>,
jobset_name: Option<String>,
page: i32,
project_name: Option<String>,
}

#[derive(Clone, Debug)]
pub enum Msg {
ChangePage(i32),
Error(responses::ResponseError),
ErrorIgnored,
Event(Event),
FetchEvaluations,
GetEvaluations(Vec<(handles::Evaluation, i64)>),
TimestampMsg(usize, timestamp::Msg),
}

pub fn init(
base_url: &Url,
orders: &mut impl Orders<Msg>,
project_name: Option<String>,
jobset_name: Option<String>,
page: i32,
) -> Model {
orders.send_msg(Msg::FetchEvaluations);
Model {
base_url: base_url.clone(),
error: None,
evaluations: Vec::new(),
jobset_name,
page,
project_name,
}
}

pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
match msg {
Msg::ChangePage(page) => {
model.page = page;
orders.send_msg(Msg::FetchEvaluations);
}
Msg::Error(err) => {
model.error = Some(err);
}
Msg::ErrorIgnored => {
model.error = None;
}
Msg::Event(_) => {
orders.send_msg(Msg::FetchEvaluations);
}
Msg::FetchEvaluations => {
let req = requests::Request::ListEvaluations(requests::EvaluationSearch {
jobset_name: model.jobset_name.clone(),
limit: 10,
offset: (model.page - 1) * 10,
project_name: model.project_name.clone(),
});
perform_request!(
orders,
req,
responses::Response::ListEvaluations(evaluations) => Msg::GetEvaluations(evaluations),
Msg::Error,
);
}
Msg::GetEvaluations(mut evaluations) => {
model.evaluations = evaluations
.drain(..)
.enumerate()
.map(|(i, (handle, time))| {
(
handle,
timestamp::init(
&mut orders.proxy(move |msg| Msg::TimestampMsg(i, msg)),
&time,
),
)
})
.collect();
}
Msg::TimestampMsg(i, msg) => {
if let Some((_, m)) = model.evaluations.iter_mut().nth(i as usize) {
timestamp::update(
msg,
m,
&mut orders.proxy(move |msg| Msg::TimestampMsg(i, msg)),
);
}
}
}
}

pub fn view(model: &Model) -> Node<Msg> {
if let Some(err) = &model.error {
view_error(&model.base_url, err, Msg::ErrorIgnored)
} else {
div![
ul![model
.evaluations
.iter()
.enumerate()
.map(|(i, (handle, time))| {
let urls = crate::Urls::new(&model.base_url);
li![
a![
handle.to_string(),
attrs! { At::Href => urls.evaluation(
handle
)},
],
" (",
timestamp::view(time).map_msg(move |msg| Msg::TimestampMsg(i, msg)),
")",
]
}),],
button![
"<",
ev(Ev::Click, {
let page = model.page;
move |_| Msg::ChangePage(page - 1)
})
],
model.page.to_string(),
button![
">",
ev(Ev::Click, {
let page = model.page;
move |_| Msg::ChangePage(page + 1)
})
],
]
}
}
1 change: 1 addition & 0 deletions typhon-webapp/src/widgets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod drv_log;
pub mod editable_text;
pub mod evaluation_list;
pub mod timestamp;

0 comments on commit ba65e91

Please sign in to comment.