From a90b5f83d88005456a0923802d7dab6d9bebcb4d Mon Sep 17 00:00:00 2001 From: Emilia Date: Fri, 12 Jan 2024 22:22:28 -0500 Subject: [PATCH] A number of moves to address #2 --- .../callbacks/main_window_callbacks.rs | 93 ++++++++++++++++++- src/components/main_window.rs | 74 +++++---------- 2 files changed, 116 insertions(+), 51 deletions(-) diff --git a/src/components/callbacks/main_window_callbacks.rs b/src/components/callbacks/main_window_callbacks.rs index c3af4ea..c7fe771 100644 --- a/src/components/callbacks/main_window_callbacks.rs +++ b/src/components/callbacks/main_window_callbacks.rs @@ -1,10 +1,18 @@ +use js_sys::Array; +use wasm_bindgen::{JsCast, JsValue}; +use web_sys::{Blob, HtmlAnchorElement, Url}; + use yew::prelude::*; use yewdux::prelude::*; use crate::components::states::{CurrentTransfer, MainState}; +use crate::data::csv::state_to_csv; + +type NoParamsCallback = Box ()>; + pub fn toggle_in_transfer_hashes_callback( - main_dispatch: &Dispatch, + main_dispatch: Dispatch, ) -> Callback { let main_dispatch = main_dispatch.clone(); Callback::from(move |_| { @@ -13,3 +21,86 @@ pub fn toggle_in_transfer_hashes_callback( }) }) } + +pub fn new_plate_dialog_callback( + new_plate_dialog_is_open: UseStateHandle, +) -> NoParamsCallback { + let new_plate_dialog_is_open = new_plate_dialog_is_open.clone(); + Box::new(move |_| { + new_plate_dialog_is_open.set(false); + }) +} + +pub fn open_new_plate_dialog_callback( + new_plate_dialog_is_open: UseStateHandle, +) -> NoParamsCallback { + let new_plate_dialog_is_open = new_plate_dialog_is_open.clone(); + Box::new(move |_| { + new_plate_dialog_is_open.set(true); + }) +} + +pub fn new_button_callback( + main_dispatch: Dispatch, + ct_dispatch: Dispatch, +) -> Callback { + Callback::from(move |_| { + let window = web_sys::window().unwrap(); + let confirm = + window.confirm_with_message("This will reset all plates and transfers. Proceed?"); + if let Ok(confirm) = confirm { + if confirm { + main_dispatch.set(MainState::default()); + ct_dispatch.set(CurrentTransfer::default()); + } + } + }) +} + +fn save_str(data: &str, name: &str) { + let blob = + Blob::new_with_str_sequence(&Array::from_iter(std::iter::once(JsValue::from_str(data)))); + if let Ok(blob) = blob { + let url = Url::create_object_url_with_blob(&blob).expect("We have a blob, why not URL?"); + // Beneath is the cool hack to download files + let window = web_sys::window().unwrap(); + let document = window.document().unwrap(); + let anchor = document + .create_element("a") + .unwrap() + .dyn_into::() + .unwrap(); + anchor.set_download(name); + anchor.set_href(&url); + anchor.click(); + } +} + +pub fn export_csv_button_callback(main_state: std::rc::Rc) -> Callback { + Callback::from(move |_| { + if main_state.transfers.is_empty() { + web_sys::window() + .unwrap() + .alert_with_message("No transfers to export.") + .unwrap(); + return; + } + web_sys::window().unwrap().alert_with_message("CSV export is currently not importable. Export as JSON if you'd like to back up your work!").unwrap(); + if let Ok(csv) = state_to_csv(&main_state) { + save_str(&csv, "transfers.csv"); + } + }) +} + +pub fn export_json_button_callback(main_state: std::rc::Rc) -> Callback { + Callback::from(move |_| { + if let Ok(json) = serde_json::to_string(&main_state) { + save_str(&json, "plate-tool-state.json"); + } else { + web_sys::window() + .unwrap() + .alert_with_message("Failed to export.") + .unwrap(); + } + }) +} diff --git a/src/components/main_window.rs b/src/components/main_window.rs index a70ce90..b3cd8fe 100644 --- a/src/components/main_window.rs +++ b/src/components/main_window.rs @@ -18,7 +18,6 @@ use crate::components::states::{CurrentTransfer, MainState}; use crate::components::transfer_menu::{letters_to_num, RegionDisplay, TransferMenu}; use crate::components::tree::Tree; -use crate::data::csv::state_to_csv; use crate::data::plate_instances::PlateInstance; use crate::data::transfer::Transfer; use crate::data::transfer_region::{Region, TransferRegion}; @@ -51,65 +50,30 @@ pub fn MainWindow() -> Html { }); } - let toggle_in_transfer_hashes_callback = main_window_callbacks::test(&main_dispatch); + let toggle_in_transfer_hashes_callback = { + let main_dispatch = main_dispatch.clone(); + main_window_callbacks::toggle_in_transfer_hashes_callback(main_dispatch) + }; let new_plate_dialog_is_open = use_state_eq(|| false); - let new_plate_dialog_callback = { - let new_plate_dialog_is_open = new_plate_dialog_is_open.clone(); - Callback::from(move |_| { - new_plate_dialog_is_open.set(false); - }) - }; - let open_new_plate_dialog_callback = { - let new_plate_dialog_is_open = new_plate_dialog_is_open.clone(); - Callback::from(move |_| { - new_plate_dialog_is_open.set(true); - }) - }; + let new_plate_dialog_callback = + main_window_callbacks::new_plate_dialog_callback(new_plate_dialog_is_open.clone()); + + let open_new_plate_dialog_callback = + main_window_callbacks::open_new_plate_dialog_callback(new_plate_dialog_is_open.clone()); let new_button_callback = { let main_dispatch = main_dispatch.clone(); - Callback::from(move |_| { - let window = web_sys::window().unwrap(); - let confirm = - window.confirm_with_message("This will reset all plates and transfers. Proceed?"); - if let Ok(confirm) = confirm { - if confirm { - main_dispatch.set(MainState::default()); - ct_dispatch.set(CurrentTransfer::default()); - } - } - }) + main_window_callbacks::new_button_callback(main_dispatch, ct_dispatch) }; let export_csv_button_callback = { let main_state = main_state.clone(); - Callback::from(move |_| { - if main_state.transfers.is_empty() { - web_sys::window() - .unwrap() - .alert_with_message("No transfers to export.") - .unwrap(); - return; - } - web_sys::window().unwrap().alert_with_message("CSV export is currently not importable. Export as JSON if you'd like to back up your work!").unwrap(); - if let Ok(csv) = state_to_csv(&main_state) { - save_str(&csv, "transfers.csv"); - } - }) + main_window_callbacks::export_csv_button_callback(main_state) }; let export_json_button_callback = { - Callback::from(move |_| { - if let Ok(json) = serde_json::to_string(&main_state) { - save_str(&json, "plate-tool-state.json"); - } else { - web_sys::window() - .unwrap() - .alert_with_message("Failed to export.") - .unwrap(); - } - }) + main_window_callbacks::export_json_button_callback(main_state) }; let import_json_button_callback = { @@ -373,8 +337,18 @@ pub fn MainWindow() -> Html { let c2 = REGEX .captures(&record.destination_well) .unwrap(); - log::debug!("{} {}", &record.source_well, &record.destination_well); - log::debug!("{},{} {},{}", &c1[1], &c1[2], &c2[1], &c2[2]); + log::debug!( + "{} {}", + &record.source_well, + &record.destination_well + ); + log::debug!( + "{},{} {},{}", + &c1[1], + &c1[2], + &c2[1], + &c2[2] + ); ( (