use std::rc::Rc; use uuid::Uuid; use wasm_bindgen::JsCast; use web_sys::{EventTarget, HtmlInputElement}; use yew::prelude::*; use yewdux::prelude::*; use crate::components::transfer_menu::RegionDisplay; use crate::data::{transfer::Transfer, transfer_region::Region}; use crate::components::states::{CurrentTransfer, MainState}; pub fn on_name_change_callback(ct_dispatch: Dispatch) -> Callback { Callback::from(move |e: Event| { let target: Option = e.target(); let input = target.and_then(|t| t.dyn_into::().ok()); if let Some(input) = input { if input.value() == "" { return; } // We do not want empty inputs! ct_dispatch.reduce_mut(|state| { state.transfer.name = input.value(); }); } }) } pub fn on_src_region_change_callback(ct_dispatch: Dispatch) -> Callback { Callback::from(move |e: Event| { if matches!( ct_dispatch.get().transfer.transfer_region.source_region, Region::Custom(_) ) { return; // Do nothing here! } let target: Option = e.target(); let input = target.and_then(|t| t.dyn_into::().ok()); if let Some(input) = input { if let Ok(rd) = RegionDisplay::try_from(input.value().to_uppercase()) { ct_dispatch.reduce_mut(|state| { state.transfer.transfer_region.source_region = Region::from(&rd); }); input.set_custom_validity(""); } else { input.set_custom_validity("Invalid region.") } } }) } pub fn on_dest_region_change_callback(ct_dispatch: Dispatch) -> Callback { Callback::from(move |e: Event| { let target: Option = e.target(); let input = target.and_then(|t| t.dyn_into::().ok()); if let Some(input) = input { if let Ok(rd) = RegionDisplay::try_from(input.value().to_uppercase()) { ct_dispatch.reduce_mut(|state| { state.transfer.transfer_region.dest_region = Region::from(&rd); }); input.set_custom_validity(""); } else { input.set_custom_validity("Invalid region.") } } }) } pub fn on_source_interleave_x_change_callback( ct_dispatch: Dispatch, ) -> Callback { Callback::from(move |e: Event| { let target: Option = e.target(); let input = target.and_then(|t| t.dyn_into::().ok()); if let Some(input) = input { if let Ok(num) = input.value().parse::() { ct_dispatch.reduce_mut(|state| { state.transfer.transfer_region.interleave_source = (num, state.transfer.transfer_region.interleave_source.1); }); } } }) } pub fn on_source_interleave_y_change_callback( ct_dispatch: Dispatch, ) -> Callback { Callback::from(move |e: Event| { let target: Option = e.target(); let input = target.and_then(|t| t.dyn_into::().ok()); if let Some(input) = input { if let Ok(num) = input.value().parse::() { ct_dispatch.reduce_mut(|state| { state.transfer.transfer_region.interleave_source = (state.transfer.transfer_region.interleave_source.0, num); }); } } }) } pub fn on_dest_interleave_x_change_callback( ct_dispatch: Dispatch, ) -> Callback { Callback::from(move |e: Event| { let target: Option = e.target(); let input = target.and_then(|t| t.dyn_into::().ok()); if let Some(input) = input { if let Ok(num) = input.value().parse::() { ct_dispatch.reduce_mut(|state| { state.transfer.transfer_region.interleave_dest = (num, state.transfer.transfer_region.interleave_dest.1); }); } } }) } pub fn on_dest_interleave_y_change_callback( ct_dispatch: Dispatch, ) -> Callback { Callback::from(move |e: Event| { let target: Option = e.target(); let input = target.and_then(|t| t.dyn_into::().ok()); if let Some(input) = input { if let Ok(num) = input.value().parse::() { ct_dispatch.reduce_mut(|state| { state.transfer.transfer_region.interleave_dest = (state.transfer.transfer_region.interleave_dest.0, num); }); } } }) } pub fn on_volume_change_callback(ct_dispatch: Dispatch) -> Callback { Callback::from(move |e: Event| { let input = e .target() .expect("Event must have target") .dyn_into::() .expect("Must have been emitted by input"); if let Ok(num) = input.value().parse::() { ct_dispatch.reduce_mut(|state| { state.transfer.volume = num; }); } }) } pub fn new_transfer_button_callback_callback( main_dispatch: Dispatch, main_state: Rc, ct_dispatch: Dispatch, ) -> Callback { Callback::from(move |_: MouseEvent| { main_dispatch.reduce_mut(|state| { state.selected_transfer = Uuid::nil(); }); ct_dispatch.reduce_mut(|state| { state.transfer = Transfer::default(); state.transfer.source_id = main_state.selected_source_plate; state.transfer.dest_id = main_state.selected_dest_plate; }); }) } pub fn save_transfer_button_callback_callback( main_dispatch: Dispatch, main_state: Rc, ct_state: Rc, new_transfer_button_callback: Callback) -> Callback { Callback::from(move |e: MouseEvent| { log::debug!("Button pressed"); if main_state.selected_transfer.is_nil() { if let Some(spi) = main_state .source_plates .iter() .find(|spi| spi.get_uuid() == main_state.selected_source_plate) { if let Some(dpi) = main_state .destination_plates .iter() .find(|dpi| dpi.get_uuid() == main_state.selected_dest_plate) { let new_transfer = Transfer::new( spi.clone(), dpi.clone(), ct_state.transfer.transfer_region.clone(), ct_state.transfer.name.clone(), ); main_dispatch.reduce_mut(|state| { state.transfers.push(new_transfer); state.selected_transfer = state .transfers .last() .expect("An element should have just been added") .get_uuid(); }); new_transfer_button_callback.emit(e); // If we just made a new transfer, // then we should make another on // save. } } } else if let Some(index) = main_state .transfers .iter() .position(|t| t.get_uuid() == main_state.selected_transfer) { main_dispatch.reduce_mut(|state| { state.transfers[index] = ct_state.transfer.clone(); }); } }) } pub fn delete_transfer_button_callback( main_state: Rc, main_dispatch: Dispatch, ct_state: Rc, new_transfer_button_callback: Callback ) -> Callback { Callback::from(move |e: MouseEvent| { if main_state.selected_transfer.is_nil() { // Maybe reset transfer? } else if let Some(index) = main_state .transfers .iter() .position(|t| t.get_uuid() == ct_state.transfer.get_uuid()) { main_dispatch.reduce_mut(|state| { state.transfers.remove(index); state.selected_transfer = Uuid::nil(); }); new_transfer_button_callback.emit(e); // We need a new transfer now } }) }