diff --git a/plate-tool-web/src/components/callbacks/main_window_callbacks/settings_callbacks.rs b/plate-tool-web/src/components/callbacks/main_window_callbacks/settings_callbacks.rs index 4b36a54..e7042a6 100644 --- a/plate-tool-web/src/components/callbacks/main_window_callbacks/settings_callbacks.rs +++ b/plate-tool-web/src/components/callbacks/main_window_callbacks/settings_callbacks.rs @@ -1,9 +1,18 @@ #![allow(non_snake_case)] +use js_sys::Function; +use wasm_bindgen::{prelude::*, JsCast}; +use web_sys::{ + FileReader, HtmlButtonElement, HtmlDialogElement, HtmlElement, HtmlFormElement, + HtmlInputElement, HtmlOptionElement, HtmlSelectElement, +}; + use yew::prelude::*; use yewdux::prelude::*; -use crate::components::states::MainState; +use crate::components::states::{CsvExportType, MainState}; + +use super::create_close_button; type NoParamsCallback = Box; @@ -28,3 +37,72 @@ pub fn toggle_volume_heatmap_callback( }) }) } + +pub fn change_csv_export_type_callback( + main_dispatch: Dispatch, +) -> Callback { + let main_dispatch = main_dispatch.clone(); + Callback::from(move |_| { + let window = web_sys::window().unwrap(); + let document = window.document().unwrap(); + let body = document.body().unwrap(); + let modal = document + .create_element("dialog") + .unwrap() + .dyn_into::() + .unwrap(); + let onclose_callback = { + let modal = modal.clone(); + Closure::::new(move |_: Event| { + modal.remove(); + }) + }; + modal.set_onclose(Some(onclose_callback.as_ref().unchecked_ref())); + modal.set_text_content(Some("CSV Export Type")); + + let close_button = create_close_button(&onclose_callback); + onclose_callback.forget(); + modal.append_child(&close_button).unwrap(); + + let form = document + .create_element("form") + .unwrap() + .dyn_into::() + .unwrap(); + let export_type = document + .create_element("select") + .unwrap() + .dyn_into::() + .unwrap(); + for t in [CsvExportType::Normal, CsvExportType::EchoClient] { + let option = document + .create_element("option") + .unwrap() + .dyn_into::() + .unwrap(); + option.set_value(&t.to_string()); + option.set_text(&t.to_string()); + option.set_selected(t == main_dispatch.get().preferences.csv_export_type); + + export_type.append_child(&option).unwrap(); + } + form.append_child(&export_type).unwrap(); + + let form_change_callback = { + let export_type = export_type.clone(); + let main_dispatch = main_dispatch.clone(); + Closure::::new(move |_: Event| { + let current: CsvExportType = export_type.value().as_str().into(); + main_dispatch.reduce_mut(|state| { + state.preferences.csv_export_type = current; + }); + })}; + form.set_onchange(Some(form_change_callback.as_ref().unchecked_ref())); + form_change_callback.forget(); + + modal.append_child(&form).unwrap(); + + body.append_child(&modal).unwrap(); + modal.show_modal().unwrap(); + }) +} diff --git a/plate-tool-web/src/components/main_window.rs b/plate-tool-web/src/components/main_window.rs index fbbba4f..c16695a 100644 --- a/plate-tool-web/src/components/main_window.rs +++ b/plate-tool-web/src/components/main_window.rs @@ -48,6 +48,11 @@ pub fn MainWindow() -> Html { main_window_callbacks::toggle_volume_heatmap_callback(main_dispatch) }; + let change_csv_export_type_callback = { + let main_dispatch = main_dispatch.clone(); + main_window_callbacks::change_csv_export_type_callback(main_dispatch) + }; + let new_plate_dialog_is_open = use_state_eq(|| false); let new_plate_dialog_callback = main_window_callbacks::new_plate_dialog_callback(new_plate_dialog_is_open.clone()); @@ -106,6 +111,12 @@ pub fn MainWindow() -> Html { +
diff --git a/plate-tool-web/src/components/states.rs b/plate-tool-web/src/components/states.rs index f98d870..5e85031 100644 --- a/plate-tool-web/src/components/states.rs +++ b/plate-tool-web/src/components/states.rs @@ -19,11 +19,40 @@ pub struct Preferences { pub in_transfer_hashes: bool, #[serde(default)] pub volume_heatmap: bool, + #[serde(default)] + pub csv_export_type: CsvExportType, } impl Default for Preferences { fn default() -> Self { - Self { in_transfer_hashes: true, volume_heatmap: false } + Self { in_transfer_hashes: true, volume_heatmap: false, csv_export_type: CsvExportType::Normal } + } +} + +#[derive(PartialEq, Clone, Copy, Serialize, Deserialize, Default)] +pub enum CsvExportType { + #[default] + Normal, + + EchoClient, +} + +impl std::fmt::Display for CsvExportType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CsvExportType::Normal => write!(f, "Normal"), + CsvExportType::EchoClient => write!(f, "Echo Client"), + } + } +} + +impl From<&str> for CsvExportType { + fn from(value: &str) -> Self { + match value.trim().to_lowercase().as_str() { + "normal" => CsvExportType::Normal, + "echo client" => CsvExportType::EchoClient, + _ => CsvExportType::default(), + } } } diff --git a/plate-tool-web/src/lib.rs b/plate-tool-web/src/lib.rs index ebc70a0..1451230 100644 --- a/plate-tool-web/src/lib.rs +++ b/plate-tool-web/src/lib.rs @@ -40,6 +40,13 @@ pub fn plate_test() { } pub fn state_to_csv(state: &MainState) -> Result> { + match state.preferences.csv_export_type { + components::states::CsvExportType::Normal => state_to_csv_regular(state), + components::states::CsvExportType::EchoClient => state_to_csv_echo_client(state) + } +} + +fn state_to_csv_regular(state: &MainState) -> Result> { let mut records: Vec = Vec::new(); for transfer in &state.transfers { let src_barcode = state @@ -60,3 +67,33 @@ pub fn state_to_csv(state: &MainState) -> Result> { } records_to_csv(records) } + +fn state_to_csv_echo_client(state: &MainState) -> Result> { + let current_src = state.selected_source_plate; + let current_dst = state.selected_dest_plate; + + let mut records: Vec = Vec::new(); + for transfer in &state.transfers { + + let src_barcode = state + .source_plates + .iter() + .find(|spi| spi.get_uuid() == transfer.source_id) + .ok_or("Found unpurged transfer")?; + + let dest_barcode = state + .destination_plates + .iter() + .find(|dpi| dpi.get_uuid() == transfer.dest_id) + .ok_or("Found unpurged transfer")?; + + if src_barcode.get_uuid() == current_src && dest_barcode.get_uuid() == current_dst { + records.append(&mut transfer_to_records( + transfer, + &src_barcode.name, + &dest_barcode.name, + )) + } + } + records_to_echo_client_csv(records) +}