bitque/jirs-client/src/modal/issue_details.rs

150 lines
4.6 KiB
Rust
Raw Normal View History

2020-04-02 23:51:29 +02:00
use seed::{prelude::*, *};
use jirs_data::{Issue, IssueType};
2020-04-03 16:15:56 +02:00
use crate::model::{EditIssueModal, ModalType, Model};
2020-04-02 23:51:29 +02:00
use crate::shared::styled_button::StyledButton;
use crate::shared::styled_icon::{Icon, StyledIcon};
use crate::shared::styled_select::{StyledSelect, Variant as SelectVariant};
use crate::shared::ToNode;
2020-04-03 16:15:56 +02:00
use crate::{FieldChange, FieldId, IssueId, Msg};
2020-04-02 23:51:29 +02:00
#[derive(PartialOrd, PartialEq, Debug)]
struct IssueTypeOption(IssueId, IssueType);
impl crate::shared::styled_select::SelectOption for IssueTypeOption {
fn into_option(self) -> Node<Msg> {
let name = self.1.to_label().to_owned();
let icon = StyledIcon::build(self.1.into())
.add_class("issueTypeIcon".to_string())
.build()
.into_node();
div![
attrs![At::Class => "type"],
icon,
div![attrs![At::Class => "typeLabel"], name]
]
}
fn into_value(self) -> Node<Msg> {
let issue_id = self.0;
let name = self.1.to_label().to_owned();
StyledButton::build()
.empty()
.children(vec![span![format!("{}-{}", name, issue_id)]])
.icon(StyledIcon::build(self.1.into()).build())
.build()
.into_node()
}
fn match_text_filter(&self, text_filter: &str) -> bool {
self.1
.to_string()
.to_lowercase()
.contains(&text_filter.to_lowercase())
}
fn to_value(&self) -> u32 {
self.1.clone().into()
}
}
pub fn view(_model: &Model, issue: &Issue, modal: &EditIssueModal) -> Node<Msg> {
let issue_id = issue.id;
let issue_type_select = StyledSelect {
id: FieldId::IssueTypeEditModalTop,
variant: SelectVariant::Empty,
dropdown_width: Some(150),
name: Some("type".to_string()),
placeholder: None,
text_filter: modal.top_select_filter.clone(),
opened: modal.top_select_opened,
valid: true,
is_multi: false,
allow_clear: false,
options: vec![
IssueTypeOption(issue_id, IssueType::Story),
IssueTypeOption(issue_id, IssueType::Task),
IssueTypeOption(issue_id, IssueType::Bug),
],
selected: vec![IssueTypeOption(issue_id, modal.value.clone())],
}
.into_node();
let click_handler = mouse_ev(Ev::Click, move |_| {
use wasm_bindgen::JsCast;
let link = format!("http://localhost:7000/issues/{id}", id = issue_id);
let el = match seed::html_document().create_element("textarea") {
Ok(el) => el
.dyn_ref::<web_sys::HtmlTextAreaElement>()
.unwrap()
.clone(),
_ => return Msg::NoOp,
};
seed::body().append_child(&el).unwrap();
el.set_text_content(Some(link.as_str()));
el.select();
el.set_selection_range(0, 9999).unwrap();
seed::html_document().exec_command("copy").unwrap();
seed::body().remove_child(&el).unwrap();
2020-04-03 16:15:56 +02:00
Msg::ModalChanged(FieldChange::LinkCopied(FieldId::CopyButtonLabel, true))
});
let close_handler = mouse_ev(Ev::Click, |_| Msg::ModalDropped);
let delete_confirmation_handler = mouse_ev(Ev::Click, move |_| {
Msg::ModalOpened(ModalType::DeleteIssueConfirm(issue_id))
2020-04-02 23:51:29 +02:00
});
let copy_button = StyledButton::build()
.empty()
.icon(Icon::Link)
.on_click(click_handler)
.children(vec![span![if modal.link_copied {
"Link Copied"
} else {
"Copy link"
}]])
.build()
.into_node();
2020-04-03 08:51:25 +02:00
let delete_button = StyledButton::build()
.empty()
.icon(Icon::Trash.into_styled_builder().size(19).build())
2020-04-03 16:15:56 +02:00
.on_click(delete_confirmation_handler)
2020-04-03 08:51:25 +02:00
.build()
.into_node();
2020-04-02 23:51:29 +02:00
let close_button = StyledButton::build()
.empty()
2020-04-03 08:51:25 +02:00
.icon(Icon::Close.into_styled_builder().size(24).build())
2020-04-03 14:40:21 +02:00
.on_click(close_handler)
2020-04-02 23:51:29 +02:00
.build()
.into_node();
div![
attrs![At::Class => "issueDetails"],
div![
attrs![At::Class => "topActions"],
issue_type_select,
div![
attrs![At::Class => "topActionsRight"],
copy_button,
delete_button,
close_button
],
],
div![
attrs![At::Class => "content"],
div![
attrs![At::Class => "left"],
div![attrs![At::Class => "title"]],
div![attrs![At::Class => "description"]],
div![attrs![At::Class => "comments"]],
],
div![attrs![At::Class => "right"]],
],
]
}