feature: Add CSV export type to plate-tool-web
This commit is contained in:
parent
b78336def0
commit
0567e0a037
|
@ -1,9 +1,18 @@
|
||||||
#![allow(non_snake_case)]
|
#![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 yew::prelude::*;
|
||||||
use yewdux::prelude::*;
|
use yewdux::prelude::*;
|
||||||
|
|
||||||
use crate::components::states::MainState;
|
use crate::components::states::{CsvExportType, MainState};
|
||||||
|
|
||||||
|
use super::create_close_button;
|
||||||
|
|
||||||
type NoParamsCallback = Box<dyn Fn(())>;
|
type NoParamsCallback = Box<dyn Fn(())>;
|
||||||
|
|
||||||
|
@ -28,3 +37,72 @@ pub fn toggle_volume_heatmap_callback(
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn change_csv_export_type_callback(
|
||||||
|
main_dispatch: Dispatch<MainState>,
|
||||||
|
) -> Callback<web_sys::MouseEvent> {
|
||||||
|
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::<HtmlDialogElement>()
|
||||||
|
.unwrap();
|
||||||
|
let onclose_callback = {
|
||||||
|
let modal = modal.clone();
|
||||||
|
Closure::<dyn FnMut(_)>::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::<HtmlFormElement>()
|
||||||
|
.unwrap();
|
||||||
|
let export_type = document
|
||||||
|
.create_element("select")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlSelectElement>()
|
||||||
|
.unwrap();
|
||||||
|
for t in [CsvExportType::Normal, CsvExportType::EchoClient] {
|
||||||
|
let option = document
|
||||||
|
.create_element("option")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlOptionElement>()
|
||||||
|
.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::<dyn FnMut(_)>::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();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -48,6 +48,11 @@ pub fn MainWindow() -> Html {
|
||||||
main_window_callbacks::toggle_volume_heatmap_callback(main_dispatch)
|
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_is_open = use_state_eq(|| false);
|
||||||
let new_plate_dialog_callback =
|
let new_plate_dialog_callback =
|
||||||
main_window_callbacks::new_plate_dialog_callback(new_plate_dialog_is_open.clone());
|
main_window_callbacks::new_plate_dialog_callback(new_plate_dialog_is_open.clone());
|
||||||
|
@ -106,6 +111,12 @@ pub fn MainWindow() -> Html {
|
||||||
<button onclick={toggle_volume_heatmap_callback}>{"Toggle volume heatmap"}</button>
|
<button onclick={toggle_volume_heatmap_callback}>{"Toggle volume heatmap"}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="dropdown-sub">
|
||||||
|
<button>{"Export"}</button>
|
||||||
|
<div>
|
||||||
|
<button onclick={change_csv_export_type_callback}>{"Change CSV export type"}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="main_container">
|
<div class="main_container">
|
||||||
|
|
|
@ -19,11 +19,40 @@ pub struct Preferences {
|
||||||
pub in_transfer_hashes: bool,
|
pub in_transfer_hashes: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub volume_heatmap: bool,
|
pub volume_heatmap: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub csv_export_type: CsvExportType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Preferences {
|
impl Default for Preferences {
|
||||||
fn default() -> Self {
|
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(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,13 @@ pub fn plate_test() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn state_to_csv(state: &MainState) -> Result<String, Box<dyn Error>> {
|
pub fn state_to_csv(state: &MainState) -> Result<String, Box<dyn Error>> {
|
||||||
|
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<String, Box<dyn Error>> {
|
||||||
let mut records: Vec<TransferRecord> = Vec::new();
|
let mut records: Vec<TransferRecord> = Vec::new();
|
||||||
for transfer in &state.transfers {
|
for transfer in &state.transfers {
|
||||||
let src_barcode = state
|
let src_barcode = state
|
||||||
|
@ -60,3 +67,33 @@ pub fn state_to_csv(state: &MainState) -> Result<String, Box<dyn Error>> {
|
||||||
}
|
}
|
||||||
records_to_csv(records)
|
records_to_csv(records)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn state_to_csv_echo_client(state: &MainState) -> Result<String, Box<dyn Error>> {
|
||||||
|
let current_src = state.selected_source_plate;
|
||||||
|
let current_dst = state.selected_dest_plate;
|
||||||
|
|
||||||
|
let mut records: Vec<TransferRecord> = 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)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue