2020-03-30 14:26:25 +02:00
|
|
|
use seed::{prelude::*, *};
|
2020-03-31 22:05:18 +02:00
|
|
|
use wasm_bindgen::JsCast;
|
2020-03-30 14:26:25 +02:00
|
|
|
|
2020-04-01 18:30:01 +02:00
|
|
|
use jirs_data::Issue;
|
|
|
|
|
2020-03-31 08:56:46 +02:00
|
|
|
use crate::model::{Icon, Model};
|
2020-04-01 18:30:01 +02:00
|
|
|
use crate::{IssueId, Msg};
|
2020-03-30 14:56:22 +02:00
|
|
|
|
2020-03-31 08:56:46 +02:00
|
|
|
pub mod aside;
|
2020-04-01 10:36:05 +02:00
|
|
|
pub mod modal;
|
2020-03-31 08:56:46 +02:00
|
|
|
pub mod navbar_left;
|
2020-03-31 11:11:06 +02:00
|
|
|
pub mod styled_avatar;
|
2020-03-30 23:19:00 +02:00
|
|
|
pub mod styled_button;
|
2020-03-31 08:56:46 +02:00
|
|
|
pub mod styled_input;
|
2020-04-01 18:30:01 +02:00
|
|
|
pub mod styled_select;
|
2020-03-30 23:19:00 +02:00
|
|
|
pub mod styled_tooltip;
|
2020-03-30 16:26:24 +02:00
|
|
|
|
2020-04-01 18:30:01 +02:00
|
|
|
pub fn find_issue(model: &Model, issue_id: IssueId) -> Option<&Issue> {
|
|
|
|
match model.project.as_ref() {
|
|
|
|
Some(p) => p.issues.iter().find(|issue| issue.id == issue_id),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 11:11:06 +02:00
|
|
|
pub trait ToNode {
|
|
|
|
fn into_node(self) -> Node<Msg>;
|
|
|
|
}
|
|
|
|
|
2020-03-30 23:19:00 +02:00
|
|
|
pub fn styled_icon(icon: Icon) -> Node<Msg> {
|
2020-04-01 22:41:26 +02:00
|
|
|
let style = icon
|
|
|
|
.to_color()
|
|
|
|
.map(|s| format!("color: {}", s))
|
|
|
|
.unwrap_or_default();
|
|
|
|
i![
|
|
|
|
attrs![At::Class => format!("styledIcon {}", icon), At::Style => style],
|
|
|
|
""
|
|
|
|
]
|
2020-03-30 23:19:00 +02:00
|
|
|
}
|
|
|
|
|
2020-03-30 14:26:25 +02:00
|
|
|
pub fn divider() -> Node<Msg> {
|
|
|
|
div![attrs![At::Class => "divider"], ""]
|
|
|
|
}
|
|
|
|
|
2020-04-01 18:30:01 +02:00
|
|
|
pub fn inner_layout(
|
|
|
|
model: &Model,
|
|
|
|
page_name: &str,
|
|
|
|
children: Vec<Node<Msg>>,
|
|
|
|
modal: Option<Node<Msg>>,
|
|
|
|
) -> Node<Msg> {
|
|
|
|
let modal_node = match modal {
|
|
|
|
Some(modal) => vec![modal],
|
|
|
|
_ => vec![],
|
|
|
|
};
|
2020-03-30 16:26:24 +02:00
|
|
|
article![
|
2020-04-01 18:30:01 +02:00
|
|
|
modal_node,
|
2020-03-31 08:56:46 +02:00
|
|
|
attrs![At::Class => "inner-layout"],
|
|
|
|
id![page_name],
|
|
|
|
navbar_left::render(model),
|
|
|
|
aside::render(model),
|
2020-03-30 16:26:24 +02:00
|
|
|
children,
|
|
|
|
]
|
2020-03-30 14:26:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn host_client(host_url: String, path: &str) -> Result<Request, String> {
|
|
|
|
let url = format!("{}{}", host_url, path);
|
|
|
|
let w = window();
|
|
|
|
let store = match w.local_storage() {
|
|
|
|
Ok(Some(store)) => store,
|
|
|
|
_ => return Err("Local storage is not available".to_string()),
|
|
|
|
};
|
|
|
|
let token = match store.get_item("authToken") {
|
|
|
|
Ok(Some(s)) => s,
|
|
|
|
_ => "".to_string(),
|
|
|
|
};
|
|
|
|
Ok(Request::new(url).header("Authorization", format!("Bearer {}", token).as_str()))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn update(msg: &Msg, model: &mut crate::model::Model, _orders: &mut impl Orders<Msg>) {
|
|
|
|
match msg {
|
2020-03-31 22:05:18 +02:00
|
|
|
Msg::CurrentProjectResult(fetched) => {
|
|
|
|
crate::api_handlers::current_project_response(fetched, model);
|
|
|
|
}
|
|
|
|
Msg::CurrentUserResult(fetched) => {
|
|
|
|
crate::api_handlers::current_user_response(fetched, model);
|
|
|
|
}
|
2020-03-30 14:26:25 +02:00
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
}
|
2020-03-31 22:05:18 +02:00
|
|
|
|
|
|
|
pub fn drag_ev<Ms>(
|
|
|
|
trigger: impl Into<Ev>,
|
|
|
|
handler: impl FnOnce(web_sys::DragEvent) -> Ms + 'static + Clone,
|
|
|
|
) -> EventHandler<Ms> {
|
|
|
|
let closure_handler = move |event: web_sys::Event| {
|
|
|
|
(handler.clone())(event.dyn_ref::<web_sys::DragEvent>().unwrap().clone())
|
|
|
|
};
|
|
|
|
EventHandler::new(trigger, closure_handler)
|
|
|
|
}
|