2023-05-21 16:45:12 +00:00
|
|
|
#![allow(non_snake_case)]
|
2023-05-22 22:11:49 +00:00
|
|
|
|
2023-05-24 01:08:32 +00:00
|
|
|
use uuid::Uuid;
|
|
|
|
use wasm_bindgen::JsCast;
|
2023-06-06 01:28:56 +00:00
|
|
|
use web_sys::{EventTarget, HtmlDialogElement, HtmlElement, HtmlInputElement};
|
2023-05-22 15:26:08 +00:00
|
|
|
use yew::prelude::*;
|
2023-05-22 22:11:49 +00:00
|
|
|
use yewdux::prelude::*;
|
|
|
|
|
2023-06-01 17:04:03 +00:00
|
|
|
use crate::components::states::{CurrentTransfer, MainState};
|
2023-05-24 15:42:54 +00:00
|
|
|
use crate::components::transfer_menu::RegionDisplay;
|
2023-05-25 16:07:21 +00:00
|
|
|
use crate::data::transfer_region::Region;
|
2023-05-21 16:45:12 +00:00
|
|
|
|
2023-05-22 22:31:02 +00:00
|
|
|
#[derive(PartialEq, Properties)]
|
|
|
|
pub struct TreeProps {
|
|
|
|
pub open_new_plate_callback: Callback<()>,
|
|
|
|
}
|
|
|
|
|
2023-05-22 15:26:08 +00:00
|
|
|
#[function_component]
|
2023-05-22 22:31:02 +00:00
|
|
|
pub fn Tree(props: &TreeProps) -> Html {
|
2023-05-24 15:20:12 +00:00
|
|
|
let (main_state, main_dispatch) = use_store::<MainState>();
|
2023-05-25 16:07:21 +00:00
|
|
|
let (ct_state, ct_dispatch) = use_store::<CurrentTransfer>();
|
2023-06-01 17:04:03 +00:00
|
|
|
let plate_modal_id: UseStateHandle<Option<Uuid>> = use_state(|| None);
|
2023-05-24 01:08:32 +00:00
|
|
|
|
|
|
|
let open_plate_info_callback = {
|
2023-06-01 17:04:03 +00:00
|
|
|
let plate_menu_id = plate_modal_id.clone();
|
2023-05-24 01:08:32 +00:00
|
|
|
Callback::from(move |e: MouseEvent| {
|
|
|
|
let target: Option<EventTarget> = e.target();
|
|
|
|
let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
|
|
|
|
if let Some(li) = li {
|
|
|
|
if let Ok(id) = u128::from_str_radix(li.id().as_str(), 10) {
|
|
|
|
plate_menu_id.set(Some(Uuid::from_u128(id)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
let plate_info_close_callback = {
|
2023-06-01 17:04:03 +00:00
|
|
|
let plate_menu_id = plate_modal_id.clone();
|
2023-05-24 01:08:32 +00:00
|
|
|
Callback::from(move |_| {
|
|
|
|
plate_menu_id.set(None);
|
|
|
|
})
|
|
|
|
};
|
|
|
|
let plate_info_delete_callback = {
|
2023-05-24 15:20:12 +00:00
|
|
|
let dispatch = main_dispatch.clone();
|
|
|
|
let plate_menu_id = plate_modal_id.clone();
|
2023-05-24 01:08:32 +00:00
|
|
|
Callback::from(move |_| {
|
|
|
|
if let Some(id) = *plate_menu_id {
|
|
|
|
dispatch.reduce_mut(|state| {
|
|
|
|
state.del_plate(id);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
2023-05-24 15:20:12 +00:00
|
|
|
let source_plate_select_callback = {
|
2023-05-25 16:07:21 +00:00
|
|
|
let main_dispatch = main_dispatch.clone();
|
|
|
|
let ct_dispatch = ct_dispatch.clone();
|
|
|
|
|
2023-05-24 15:20:12 +00:00
|
|
|
Callback::from(move |e: MouseEvent| {
|
|
|
|
let target: Option<EventTarget> = e.target();
|
|
|
|
let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
|
|
|
|
if let Some(li) = li {
|
|
|
|
if let Ok(id) = u128::from_str_radix(li.id().as_str(), 10) {
|
2023-05-25 16:07:21 +00:00
|
|
|
ct_dispatch.reduce_mut(|state| {
|
2023-06-01 17:04:03 +00:00
|
|
|
state.transfer.transfer_region.source_region = Region::default();
|
2023-06-05 18:31:50 +00:00
|
|
|
state.transfer.transfer_region.dest_region = Region::default();
|
2023-05-25 16:07:21 +00:00
|
|
|
});
|
|
|
|
main_dispatch.reduce_mut(|state| {
|
|
|
|
state.selected_source_plate = Uuid::from_u128(id);
|
2023-06-01 17:04:03 +00:00
|
|
|
state.selected_transfer = Uuid::nil();
|
2023-05-25 16:07:21 +00:00
|
|
|
});
|
2023-05-24 15:20:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
let destination_plate_select_callback = {
|
2023-05-25 16:07:21 +00:00
|
|
|
let main_dispatch = main_dispatch.clone();
|
|
|
|
let ct_dispatch = ct_dispatch.clone();
|
|
|
|
|
2023-05-24 15:20:12 +00:00
|
|
|
Callback::from(move |e: MouseEvent| {
|
|
|
|
let target: Option<EventTarget> = e.target();
|
|
|
|
let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
|
|
|
|
if let Some(li) = li {
|
|
|
|
if let Ok(id) = u128::from_str_radix(li.id().as_str(), 10) {
|
2023-05-25 16:07:21 +00:00
|
|
|
ct_dispatch.reduce_mut(|state| {
|
2023-06-05 18:31:50 +00:00
|
|
|
state.transfer.transfer_region.source_region = Region::default();
|
2023-06-01 17:04:03 +00:00
|
|
|
state.transfer.transfer_region.dest_region = Region::default();
|
2023-05-25 16:07:21 +00:00
|
|
|
});
|
|
|
|
main_dispatch.reduce_mut(|state| {
|
|
|
|
state.selected_dest_plate = Uuid::from_u128(id);
|
2023-06-01 17:04:03 +00:00
|
|
|
state.selected_transfer = Uuid::nil();
|
2023-05-25 16:07:21 +00:00
|
|
|
});
|
2023-05-24 15:20:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
2023-05-24 01:08:32 +00:00
|
|
|
|
2023-06-01 17:04:03 +00:00
|
|
|
let transfer_select_callback = {
|
|
|
|
let main_state = main_state.clone();
|
|
|
|
let main_dispatch = main_dispatch.clone();
|
|
|
|
let ct_dispatch = ct_dispatch.clone();
|
|
|
|
|
|
|
|
Callback::from(move |e: MouseEvent| {
|
|
|
|
let target: Option<EventTarget> = e.target();
|
|
|
|
let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
|
|
|
|
if let Some(li) = li {
|
|
|
|
if let Ok(id) = u128::from_str_radix(li.id().as_str(), 10) {
|
|
|
|
let id = Uuid::from_u128(id);
|
2023-06-07 20:14:19 +00:00
|
|
|
if let Some(transfer) = main_state
|
|
|
|
.transfers
|
|
|
|
.iter()
|
|
|
|
.find(|transfer| transfer.get_uuid() == id)
|
|
|
|
{
|
2023-06-01 17:04:03 +00:00
|
|
|
main_dispatch.reduce_mut(|state| {
|
|
|
|
state.selected_source_plate = transfer.source_id;
|
|
|
|
state.selected_dest_plate = transfer.dest_id;
|
|
|
|
state.selected_transfer = id;
|
|
|
|
});
|
|
|
|
ct_dispatch.reduce_mut(|state| {
|
|
|
|
state.transfer = transfer.clone();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
let source_plates = main_state
|
|
|
|
.source_plates
|
|
|
|
.iter()
|
2023-05-22 22:11:49 +00:00
|
|
|
.map(|spi| {
|
2023-06-01 17:04:03 +00:00
|
|
|
html! { <li id={spi.get_uuid().as_u128().to_string()}
|
|
|
|
ondblclick={open_plate_info_callback.clone()}
|
|
|
|
onclick={source_plate_select_callback.clone()}
|
|
|
|
class={classes!(
|
|
|
|
if spi.get_uuid() == main_state.selected_source_plate {Some("selected")}
|
|
|
|
else {None}
|
|
|
|
)}>
|
|
|
|
{String::from(spi)}
|
|
|
|
</li> }
|
|
|
|
})
|
|
|
|
.collect::<Html>();
|
|
|
|
let dest_plates = main_state
|
|
|
|
.destination_plates
|
|
|
|
.iter()
|
2023-05-24 15:20:12 +00:00
|
|
|
.map(|dpi| {
|
2023-06-01 17:04:03 +00:00
|
|
|
html! { <li id={dpi.get_uuid().as_u128().to_string()}
|
|
|
|
ondblclick={open_plate_info_callback.clone()}
|
|
|
|
onclick={destination_plate_select_callback.clone()}
|
|
|
|
class={classes!(
|
|
|
|
if dpi.get_uuid() == main_state.selected_dest_plate {Some("selected")}
|
|
|
|
else {None}
|
|
|
|
)}> {String::from(dpi)} </li> }
|
|
|
|
})
|
|
|
|
.collect::<Html>();
|
|
|
|
let transfers = main_state
|
|
|
|
.transfers
|
|
|
|
.iter()
|
2023-05-27 17:12:58 +00:00
|
|
|
.map(|transfer| {
|
2023-06-01 17:04:03 +00:00
|
|
|
html! { <li id={transfer.get_uuid().as_u128().to_string()}
|
|
|
|
onclick={transfer_select_callback.clone()}
|
|
|
|
class={classes!(
|
|
|
|
if transfer.get_uuid() == main_state.selected_transfer {Some("selected")}
|
|
|
|
else {None})}>
|
2023-05-27 17:12:58 +00:00
|
|
|
{transfer.name.clone()}
|
|
|
|
</li>
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect::<Html>();
|
2023-05-22 22:11:49 +00:00
|
|
|
|
2023-05-22 15:26:08 +00:00
|
|
|
html! {
|
|
|
|
<div class="tree">
|
2023-05-22 22:11:49 +00:00
|
|
|
<div id="source-plates">
|
|
|
|
<h3>{"Source Plates:"}</h3>
|
|
|
|
<ul>
|
|
|
|
{source_plates}
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
<div id="destination-plates">
|
|
|
|
<h3>{"Destination Plates:"}</h3>
|
|
|
|
<ul>
|
|
|
|
{dest_plates}
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
<div id="transfers">
|
|
|
|
<h3>{"Transfers:"}</h3>
|
|
|
|
<ul>
|
2023-05-27 17:12:58 +00:00
|
|
|
{transfers}
|
2023-05-22 22:11:49 +00:00
|
|
|
</ul>
|
|
|
|
</div>
|
2023-05-24 15:20:12 +00:00
|
|
|
if let Some(id) = *plate_modal_id {
|
2023-05-24 01:08:32 +00:00
|
|
|
<PlateInfoModal id={id} dialog_close_callback={plate_info_close_callback}
|
|
|
|
delete_button_callback={plate_info_delete_callback}/>
|
|
|
|
}
|
2023-06-02 20:26:20 +00:00
|
|
|
|
|
|
|
<div id="controls">
|
2023-05-22 22:31:02 +00:00
|
|
|
<button type="button"
|
|
|
|
onclick={
|
|
|
|
let open_new_plate_callback = props.open_new_plate_callback.clone();
|
|
|
|
move |_| {open_new_plate_callback.emit(())}
|
|
|
|
}>
|
|
|
|
{"New Plate"}</button>
|
2023-05-22 22:11:49 +00:00
|
|
|
</div>
|
2023-05-22 15:26:08 +00:00
|
|
|
</div>
|
|
|
|
}
|
2023-05-21 16:45:12 +00:00
|
|
|
}
|
2023-05-24 01:08:32 +00:00
|
|
|
|
|
|
|
#[derive(PartialEq, Properties)]
|
|
|
|
struct PlateInfoModalProps {
|
|
|
|
id: Uuid,
|
|
|
|
dialog_close_callback: Callback<()>,
|
|
|
|
delete_button_callback: Callback<()>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[function_component]
|
|
|
|
fn PlateInfoModal(props: &PlateInfoModalProps) -> Html {
|
2023-06-06 01:28:56 +00:00
|
|
|
let (main_state, main_dispatch) = use_store::<MainState>();
|
2023-05-24 01:08:32 +00:00
|
|
|
let dialog_ref = use_node_ref();
|
|
|
|
|
2023-06-06 01:28:56 +00:00
|
|
|
let mut plate = main_state
|
2023-06-01 17:04:03 +00:00
|
|
|
.source_plates
|
|
|
|
.iter()
|
|
|
|
.find(|spi| spi.get_uuid() == props.id);
|
2023-05-24 01:08:32 +00:00
|
|
|
if plate == None {
|
2023-06-06 01:28:56 +00:00
|
|
|
plate = main_state
|
2023-06-01 17:04:03 +00:00
|
|
|
.destination_plates
|
|
|
|
.iter()
|
|
|
|
.find(|dpi| dpi.get_uuid() == props.id);
|
2023-05-24 01:08:32 +00:00
|
|
|
}
|
|
|
|
let plate_name = match plate {
|
|
|
|
Some(plate) => plate.name.clone(),
|
2023-06-01 17:04:03 +00:00
|
|
|
None => "Not Found".to_string(),
|
2023-05-24 01:08:32 +00:00
|
|
|
};
|
|
|
|
let onclose = {
|
|
|
|
let dialog_close_callback = props.dialog_close_callback.clone();
|
2023-06-01 17:04:03 +00:00
|
|
|
move |_| dialog_close_callback.emit(())
|
2023-05-24 01:08:32 +00:00
|
|
|
};
|
|
|
|
|
2023-06-06 01:28:56 +00:00
|
|
|
let rename_onchange = {
|
|
|
|
let main_dispatch = main_dispatch.clone();
|
|
|
|
let id = props.id;
|
|
|
|
Callback::from(move |e: Event| {
|
|
|
|
log::debug!("Changed name");
|
2023-06-07 20:14:19 +00:00
|
|
|
let input = e
|
|
|
|
.target()
|
|
|
|
.expect("Event must have target")
|
|
|
|
.dyn_into::<HtmlInputElement>()
|
|
|
|
.unwrap();
|
|
|
|
main_dispatch.reduce_mut(|state| state.rename_plate(id, &input.value()))
|
2023-06-06 01:28:56 +00:00
|
|
|
})
|
|
|
|
};
|
|
|
|
|
2023-05-24 01:08:32 +00:00
|
|
|
let delete_onclick = {
|
|
|
|
let delete_button_callback = props.delete_button_callback.clone();
|
|
|
|
let dialog_ref = dialog_ref.clone();
|
|
|
|
move |_| {
|
|
|
|
delete_button_callback.emit(());
|
|
|
|
dialog_ref.cast::<HtmlDialogElement>().unwrap().close();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
{
|
|
|
|
let dialog_ref = dialog_ref.clone();
|
|
|
|
|
2023-06-01 17:04:03 +00:00
|
|
|
use_effect_with_deps(
|
|
|
|
|dialog_ref| {
|
|
|
|
dialog_ref
|
|
|
|
.cast::<HtmlDialogElement>()
|
|
|
|
.unwrap()
|
|
|
|
.show_modal()
|
|
|
|
.ok();
|
|
|
|
},
|
|
|
|
dialog_ref,
|
|
|
|
);
|
2023-05-24 01:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
html! {
|
2023-06-06 22:46:04 +00:00
|
|
|
<dialog ref={dialog_ref} class="dialog" onclose={onclose}>
|
2023-05-24 01:08:32 +00:00
|
|
|
<h2>{"Plate Info"}</h2>
|
2023-06-06 22:46:04 +00:00
|
|
|
<h3>{"Name: "}<input type="text" value={plate_name} onchange={rename_onchange}/></h3>
|
2023-05-24 01:08:32 +00:00
|
|
|
<button onclick={delete_onclick}>{"Delete"}</button>
|
2023-06-06 22:46:04 +00:00
|
|
|
<form class="modal_close" method="dialog"><button /></form>
|
2023-05-24 01:08:32 +00:00
|
|
|
</dialog>
|
|
|
|
}
|
|
|
|
}
|